标签:
T1
题目大意:一棵支持当前和历史最大值查询的,有区间加、区间覆盖操作的线段树。
思路:考试的时候,只会骗分了(小的数据就暴力,大的就忽略掉历史最大值的查询然后线段树,把操作都看做*a+b的形式,然后。。。)。后来看了正解,也是看了好久才懂。用六个变量:maxn,pmaxn,add,padd,c,pc来保存一个节点的信息。建树、操作、查询都没有特殊的,就是pushdown的时候,真心美(sang)丽(bing),具体的就不在这里写了,直接上code吧。
注意:1)如果有覆盖,就忽略掉区间加;如果有区间加,就尽量放到覆盖的值上;2)要特别注意带p的变量的更新。。。
#include<iostream> #include<cstdio> #define ri -1<<31 using namespace std; struct use{ int maxn,pmaxn,add,padd,c,pc; }tree[400000]; int a[100001]={0}; char ch; void updata(int i) { tree[i].maxn=max(tree[i*2].maxn,tree[i*2+1].maxn); tree[i].pmaxn=max(tree[i*2].pmaxn,tree[i*2+1].pmaxn); } void pushdown(int i) { int j,son; for (j=0;j<=1;++j) { son=i*2+j; tree[son].pmaxn=max(tree[son].pmaxn,max(tree[i].pc,tree[son].maxn+tree[i].padd)); if (tree[son].c==ri) tree[son].padd=max(tree[son].padd,tree[son].add+tree[i].padd); else tree[son].pc=max(tree[son].pc,tree[son].c+tree[i].padd); if (tree[i].add) { if (tree[son].c!=ri) tree[son].c+=tree[i].add; else tree[son].add+=tree[i].add; tree[son].maxn+=tree[i].add; } if (tree[i].c!=ri) { tree[son].maxn=tree[son].c=tree[i].c; tree[son].add=0; } tree[son].pc=max(tree[son].pc,max(tree[son].c,tree[i].pc)); tree[son].padd=max(tree[son].padd,tree[son].add); } tree[i].padd=tree[i].add=0; tree[i].pc=tree[i].c=ri; } void build(int i,int l,int r) { int mid; tree[i].add=tree[i].padd=0; tree[i].c=tree[i].pc=ri; if (l==r) { tree[i].maxn=tree[i].pmaxn=a[l]; return; } mid=(l+r)/2; build(i*2,l,mid); build(i*2+1,mid+1,r); updata(i); } int ask(int i,int l,int r,int ll,int rr) { int mid,maxn; if (l!=r) pushdown(i); if (ll<=l&&r<=rr) { if (ch==‘Q‘) return tree[i].maxn; else return tree[i].pmaxn; } mid=(l+r)/2;maxn=ri; if (ll<=mid) maxn=max(maxn,ask(i*2,l,mid,ll,rr)); if (rr>mid) maxn=max(maxn,ask(i*2+1,mid+1,r,ll,rr)); return maxn; } void work(int i,int l,int r,int ll,int rr,int cc) { int mid; if (l!=r) pushdown(i); if (ll<=l&&r<=rr) { if (ch==‘P‘) { tree[i].maxn+=cc;tree[i].add+=cc;tree[i].padd+=cc; } else { tree[i].c=tree[i].pc=tree[i].maxn=cc; } if (tree[i].maxn>tree[i].pmaxn) tree[i].pmaxn=tree[i].maxn; return; } mid=(l+r)/2; if (ll<=mid) work(i*2,l,mid,ll,rr,cc); if (rr>mid) work(i*2+1,mid+1,r,ll,rr,cc); updata(i); } int main() { freopen("matrix.in","r",stdin); freopen("matrix.out","w",stdout); int t,i,j,e,x,y,z; scanf("%d",&t); for (i=1;i<=t;++i) scanf("%d",&a[i]); build(1,1,t); scanf("%d",&e); for (i=1;i<=e;++i) { while(scanf("%c",&ch)==1) if (ch>=‘A‘&&ch<=‘Z‘) break; if (ch==‘Q‘||ch==‘A‘) { scanf("%d%d",&x,&y); printf("%d\n",ask(1,1,t,x,y)); } else { scanf("%d%d%d",&x,&y,&z); work(1,1,t,x,y,z); } } fclose(stdin); fclose(stdout); }
标签:
原文地址:http://www.cnblogs.com/Rivendell/p/4309736.html