POJ 3468 A Simple Problem with Integers (线段树)

来源:互联网 发布:北京日知图书有限公司 编辑:程序博客网 时间:2024/06/05 07:46

第一次做线段树的题目,之前看过一点线段树的内容,自以为懂了,结果一提交TLE后来上网看了知道了延迟更新,终于1600msA了

顺便说一下延迟更新问题,如果我们仔细观察线段树的更新操作,其实更新是o(L*lgN)级别的因为要更新到叶子为止

但是其实更新并不需要更新到叶子节点,只需要搜索到等大的区间时在此区间上做个标记即可,复杂度为o(lgN),比如更新[1,5]这个区间,只需要在[1,5]区间上(如果分成n个区间段就在各个区间段)上添加一个add_to_all的段,把值加到这个段上即可。

查的时候将add_to_all的值不断增加下推即可

给出代码


#include <stdio.h>struct node{int right;int left;long long sum;long long tototal;}tree[1000000];void init(int left,int right,int now,long long value,int des){int middle=(left+right)>>1;tree[now].left=left;tree[now].right=right;tree[now].sum+=value;if (left != right){if(des>middle){init(middle+1,right,(now<<1)+2,value,des);}else{init(left,middle,(now<<1)+1,value,des);}}return;}long long sum(int left,int right,int now){int middle=(tree[now].left+tree[now].right)>>1;if(left != tree[now].left || right != tree[now].right){if(left > middle){return sum(left,right,(now<<1)+2)+tree[now].tototal*(right-left+1);}else{if(right <= middle){return sum(left,right,(now<<1)+1)+tree[now].tototal*(right-left+1);}else{return sum(left,middle,(now<<1)+1)+sum(middle+1,right,(now<<1)+2)+tree[now].tototal*(right-left+1);}}}else{return tree[now].sum+tree[now].tototal*(right-left+1);}}void add(int left,int right,int now,int addvalue){int middle=(tree[now].left+tree[now].right)>>1;if(left == tree[now].left && right == tree[now].right){tree[now].tototal+=addvalue;return;}tree[now].sum+=addvalue*(right-left+1);if(tree[now].left != tree[now].right){if(left > middle){add(left,right,(now<<1)+2,addvalue);}else{if(right <= middle){add(left,right,(now<<1)+1,addvalue);}else{add(left,middle,(now<<1)+1,addvalue);add(middle+1,right,(now<<1)+2,addvalue);}}}return;}int main(){int N,Q,i,a,b,addvalue;long long value;char tmp;//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);scanf("%d %d",&N,&Q);for(i=0;i<N;++i){scanf("%I64d",&value);init(0,N-1,0,value,i);}for(i=0;i<Q;++i){getchar();scanf("%c %d %d",&tmp,&a,&b);if('Q' == tmp){printf("%I64d\n",sum(a-1,b-1,0));}else{scanf("%d",&addvalue);add(a-1,b-1,0,addvalue);}}return 0;}


原创粉丝点击