poj3468

来源:互联网 发布:剑网三 坐标数据导入 编辑:程序博客网 时间:2024/05/17 00:16

回家2天多,都在搞线段树了,第一是回家效率也不是很高,第二是线段树也不是很容易搞,前面说了poj2777的一道线段树,那题需要lazy,现在觉得,要是不用lazy的线段树好像不是很正规似的。这里突然想到一点,其实有些做法是无法用lazy实现的,像前面那题着色,单单只是覆盖,比如说你在一个区间多次覆盖了不同的颜色,但是你需要查询该区间的左右儿子时,你传递过去的只是最新的那个颜色,这样是比较容易实现的,再说说poj3468这题,试着考虑刚才类似的问题,假如我多次向某个区间做了add操作,那么那个区间节点该保存什么呢,当然是所有加的数的和,所以这里add是需要累加的,其实对它的儿子节点来说,就是加a,加b,等价于一次性把a+b都加上了。但是我想肯定有些操作是无法lazy的,但是我好像没想出来。

poj3468代码如下

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;struct node{int l,r;long long add,sum;}tr[500001];int a[100001];void cre(int l,int r,int node){tr[node].l=l;tr[node].r=r;tr[node].add=0;tr[node].sum=0;if(l==r)return ;int mid=(l+r)/2;cre(l,mid,node*2);cre(mid+1,r,node*2+1);return ;}long long getsum(int l,int r,int node){if(l==tr[node].l&&tr[node].r==r)return tr[node].sum;if(tr[node].add!=0){tr[2*node].add+=tr[node].add;tr[2*node+1].add+=tr[node].add;tr[2*node].sum+=tr[node].add*(tr[2*node].r-tr[2*node].l+1);tr[2*node+1].sum+=tr[node].add*(tr[2*node+1].r-tr[2*node+1].l+1);tr[node].add=0;}int mid=(tr[node].l+tr[node].r)/2;long long c,c1,c2;if(l>mid)c=getsum(l,r,2*node+1);else if(r<=mid)c=getsum(l,r,2*node);else {c1=getsum(l,mid,2*node);c2=getsum(mid+1,r,2*node+1);c=c1+c2;}return c;}long long upd(int l,int r,int ad,int node){if(l==tr[node].l&&tr[node].r==r){tr[node].add+=ad;tr[node].sum+=ad*(r-l+1);return tr[node].sum;}if(tr[node].add!=0){tr[2*node].add+=tr[node].add;tr[2*node+1].add+=tr[node].add;tr[2*node].sum+=tr[node].add*(tr[2*node].r-tr[2*node].l+1);tr[2*node+1].sum+=tr[node].add*(tr[2*node+1].r-tr[2*node+1].l+1);tr[node].add=0;}int mid=(tr[node].l+tr[node].r)/2;long long c1,c2;if(mid>=r){c1=upd(l,r,ad,2*node);c2=getsum(mid+1,tr[node].r,2*node+1);}else if(mid<l){c1=getsum(tr[node].l,mid,2*node);c2=upd(l,r,ad,2*node+1);}else{c1=upd(l,mid,ad,2*node);c2=upd(mid+1,r,ad,2*node+1);}tr[node].sum=c1+c2;return tr[node].sum;}int n,o;int main(){while(~scanf("%d%d",&n,&o)){int i;cre(1,n,1);for(i=1;i<=n;i++){scanf("%d",a+i);upd(i,i,a[i],1);}while(o--){int a,b,c;char op[2];scanf("%s",op);if(op[0]=='C'){scanf("%d%d%d",&a,&b,&c);upd(a,b,c,1);}else if(op[0]=='Q'){scanf("%d%d",&a,&b);printf("%lld\n",getsum(a,b,1));}}}return 0;}


原创粉丝点击