hdu4027
http://acm.hdu.edu.cn/showproblem.php?pid=4027
思路:这一题不能用成段更新,那样会超时的。仔细看题,会发现一个2的64次方被开8次就会变成1,也就是如果一段区间和等于它的右极限-左极限+1的话,就代表这段区间不用再被开方了......接下来就是区间求和的问题了..............
#include<iostream>
#include<math.h>
using namespace std;
struct node
{
__int64 l,r,num;
}str[900010];
__int64 yy[500006],ans=0;
void build(__int64 i,__int64 l,__int64 r)
{
__int64 mid=(l+r)/2;
str[i].l=l;
str[i].r=r;
str[i].num=0;
if(l==r)
{
str[i].num=yy[l];
return;
}
build(i*2,l,mid);
build(i*2+1,mid+1,r);
str[i].num=str[i*2].num+str[i*2+1].num;
}
void updata(__int64 i,__int64 l,__int64 r)
{
__int64 mid=(str[i].l+str[i].r)/2;
if(l==str[i].l&&r==str[i].r)
{
if(str[i].num==r-l+1)
return;
else
if(l==r)
{
str[i].num=sqrt((double)str[i].num);
__int64 count=i/2;
while(count>=1)
{
str[count].num=str[count*2].num+str[count*2+1].num;
count/=2;
}
return ;
}
}
if(r<=mid)
updata(i*2,l,r);
else
if(l>mid)
updata(i*2+1,l,r);
else
{
updata(i*2,l,mid);
updata(i*2+1,mid+1,r);
}
}
__int64 getsum(__int64 i,__int64 l,__int64 r)
{
__int64 mid=(str[i].l+str[i].r)/2;
if(str[i].l==l&&str[i].r==r)
{
return str[i].num;
}
else
if(r<=mid)
return getsum(i*2,l,r);
else
if(l>mid)
return getsum(i*2+1,l,r);
else
return getsum(i*2,l,mid)+getsum(i*2+1,mid+1,r);
}
int main()
{
__int64 n,temp=0;
while(scanf("%I64d",&n)>0)
{
__int64 i;
for(i=1;i<=n;i++)
{
scanf("%I64d",&yy[i]);
}
__int64 m;
scanf("%I64d",&m);
build(1,1,n);
printf("Case #%I64d:\n",++temp);
for(i=1;i<=m;i++)
{
__int64 a,b,c;
scanf("%I64d%I64d%I64d",&a,&b,&c);
if(b>c)
{
__int64 asd;
asd=b;
b=c;
c=asd;
}
if(a==0)
{
updata(1,b,c);
}
else
if(a==1)
{
ans=0;
ans=getsum(1,b,c);
printf("%I64d\n",ans);
}
}
printf("\n");
}
return 0;
}
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。

浙公网安备 33010602011771号