您的位置:首页 > 其它

HDU 5239 Doom 线段树+找规律

2016-05-20 21:28 387 查看
import java.math.BigInteger;
import java.util.Scanner;

public class Main {
public static void main(String args[]){
//Scanner cin=new Scanner(System.in);
BigInteger a=BigInteger.valueOf(5);
BigInteger d = BigInteger.valueOf((long) (Math.pow(2, 63)-Math.pow(2,31)));

for(int i=1;i<=19;i++)
{
for(int j=1;j<=i;j++)
{
a=a.multiply(a);

a=a.mod(d);
System.out.println(a);
}
}
}
}


给出n个数和一个初始值为0的答案。每次操作给出一个区间[l,r],把区间所有的数加到答案中,之后把区间的每个数都平方。每次操作都需要输出答案

mod=9223372034707292160

这道题在做的时候没敢去做,主要是怕超时因为每次更新是很费时间的,但是后来看看题解发现是有规律

a=(a*a)%mod 经过有限次运算之后就可以的到一个不变的值用来防止超时

可以用java 打表看出来。

思路:这道题用线段树维护求和 ,

今后遇到比较大的数时,比较难算的运算时,可以考虑是否可以通过

1.循环节

2.经过几轮之后就不改变的

等特性来减少时间

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define bug puts("********************")
#define LL unsigned long long
#define mod 9223372034707292160
using namespace std;
LL val[100010*4];
LL sum[100010*4];
int cnt[100010*4];

LL quick_add(LL x,LL y)
{
LL ans=0;
while(y)
{
if(y&1)
{
ans=(ans+x)%mod;
}
y>>=1;
x=(x+x)%mod;
}
return ans;
}
LL push_up(int ind)
{
sum[ind]=(sum[ind<<1]+sum[ind<<1|1])%mod;
cnt[ind]=min(cnt[ind<<1],cnt[ind<<1|1]);
}
void Build(int l,int r,int ind)
{
if(l==r)
{
sum[ind]=val[r];         ///注意val[]下标为r或l
cnt[ind]=0;
return ;
}
int mid=(l+r)>>1;
Build(l,mid,ind<<1);
Build(mid+1,r,ind<<1|1);
push_up(ind);
}
LL query(int L,int R,int l,int r,int ind)
{
if(l<=L&&r>=R)
return sum[ind];

LL S=0;
int mid=(L+R)>>1;
if(l<=mid)  S+=query(L,mid,l,r,ind<<1);
S%=mod;
if(r>mid) S+=query(mid+1,R,l,r,ind<<1|1);
return S%mod;
}
void update(int L,int R,int l,int r,int ind)
{
if(cnt[ind]>=30)
return ;
if(L==R)
{
sum[ind]=quick_add(sum[ind],sum[ind]);
cnt[ind]++;
return ;
}
int mid=(L+R)>>1;
if(l<=mid)
update(L,mid,l,r,ind<<1);
if(r>mid)
update(mid+1,R,l,r,ind<<1|1);
push_up(ind);
}
int main()
{
LL sm=5;
for(int i=0;i<10;i++)
for(int j=1;j<=i;j++)
{
sm=sm*sm%mod;
printf("%llu\n",sm);
}

int n,t,m;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%llu",&val[i]);
Build(1,n,1);
printf("Case #%d:\n",cas);
LL Sum=0;
while(m--)
{
int l,r;
scanf("%d%d",&l,&r);
Sum+=query(1,n,l,r,1);
Sum%=mod;
printf("%llu\n",Sum);
update(1,n,l,r,1);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: