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; }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。