线段树
简单题意:
区间(单点?)更新,区间求和
这道题不用延迟操作
//注意: //1:查询时的区间端点可能前面的比后面的大; //2:优化:因为每次更新都是开平方,同一个数更新有限次数就一直是1了,所以可以这样优化 #include <stdio.h> #include<math.h> #define N 100010 #define LL __int64 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 LL sum[N<<2]; void PushUP(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void Build(int l,int r,int rt) { if(l==r) { scanf("%I64d",&sum[rt]); return; } int m=(l+r)>>1; Build(lson); Build(rson); PushUP(rt); } void Update(int L,int R,int l,int r,int rt) { if(l==r) { sum[rt]=(__int64)sqrt((double)sum[rt]); return; } int m=(l+r)>>1; if(L<=m) Update(L,R,lson); if(R>m) Update(L,R,rson); PushUP(rt); } LL Query(int L,int R,int l,int r,int rt) { if(L<=l&&R>=r) return sum[rt]; int m=(l+r)>>1; LL ret=0; if(L<=m) ret+=Query(L,R,lson); if(R>m) ret+=Query(L,R,rson); return ret; } int main() { int m,n,id=1; LL anss; while(scanf("%d",&n)!=EOF) { Build(1,n,1); scanf("%d",&m); printf("Case #%d:\n",id++); while(m--) { int q,a,b,c; scanf("%d%d%d",&q,&a,&b); if(a>b) { c=a; a=b; b=c; } anss=Query(a,b,1,n,1); if(q==1) { printf("%I64d\n",anss); } else { if(anss != b-a+1) Update(a,b,1,n,1); } } printf("\n"); } return 0; }
虽然我自己不会写线段树,但是以后遇到 区间(单点?)更新,区间求和,这可以当底板修改一下就可以用了,毕竟这里的用法还是蛮好理解的
HDU 4027 Can you answer these queries?(线段树,区间更新,区间查询),布布扣,bubuko.com
HDU 4027 Can you answer these queries?(线段树,区间更新,区间查询)
原文:http://www.cnblogs.com/laiba2004/p/3722210.html