Bzoj 1251: 序列终结者 (Splay 模板题)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bzoj 1251: 序列终结者 (Splay 模板题)相关的知识,希望对你有一定的参考价值。
就是维护一个区间加,区间翻转和区间最大值。
贴一个风格以后可以一直用
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define N 100000 6 #define XX getchar() 7 using namespace std; 8 int ch[N][2],fa[N],rev[N],ad[N],b[N],mx[N],n,m,rt,sz[N],tot,a[N]; 9 inline int read() 10 { int flag=1;char c=XX;for(;c<‘0‘||c>‘9‘;c=XX){if (c==‘-‘) flag=-1;} 11 int x=0;for(;c>=‘0‘&&c<=‘9‘;x=x*10+c-48,c=XX);return x*flag; 12 } 13 inline void Mark_rev(int x){if(!x) return;swap(ch[x][0],ch[x][1]),rev[x]^=1;} 14 inline void Mark_add(int x,int v){if(!x) return;b[x]+=v,mx[x]+=v;ad[x]+=v;} 15 inline void Push_down(int x) 16 { if (rev[x]){Mark_rev(ch[x][0]),Mark_rev(ch[x][1]),rev[x]^=1;} 17 if (ad[x]){Mark_add(ch[x][0],ad[x]),Mark_add(ch[x][1],ad[x]),ad[x]=0;} 18 } 19 inline void Push_up(int x) 20 { mx[x]=b[x],sz[x]=1;if(ch[x][0])mx[x]=max(mx[x],mx[ch[x][0]]),sz[x]+=sz[ch[x][0]]; 21 if(ch[x][1])mx[x]=max(mx[x],mx[ch[x][1]]),sz[x]+=sz[ch[x][1]]; 22 } 23 void rot(int x) 24 { int y=fa[x],d=ch[y][1]==x; 25 fa[ch[x][d^1]]=y,ch[y][d]=ch[x][d^1]; 26 if (fa[y]) ch[fa[y]][ch[fa[y]][1]==y]=x; 27 fa[x]=fa[y];fa[y]=x;ch[x][d^1]=y;Push_up(y); 28 } 29 void Splay(int x,int goal) 30 { int s=1,i=x;a[1]=x; 31 while (fa[i]) a[++s]=(i=fa[i]);while(s) Push_down(a[s--]); 32 while (fa[x]!=goal){int y=fa[x];if(fa[y]==goal){rot(x);continue;} 33 if ((ch[y][0]==x)^(ch[fa[y]][0]==y))rot(y);else rot(x);rot(x);} 34 Push_up(x);if (goal==0) rt=x; 35 } 36 int Building(int l,int r,int f) 37 { int x=++tot,mid =(l+r)>>1; 38 fa[x]=f;b[x]=0;if(l<mid) ch[x][0]=Building(l,mid-1,x); 39 if (r>mid) ch[x][1]=Building(mid+1,r,x); Push_up(x); return x; 40 } 41 int Find_kth(int k) 42 { int x=rt,tmp; 43 while (1) 44 { Push_down(x);tmp=sz[ch[x][0]]+1;if (k==tmp) return x; 45 if (k<tmp) x=ch[x][0];else k-=tmp, x=ch[x][1]; 46 } 47 } 48 void Add(int l,int r,int v) 49 { Splay(Find_kth(l),0);Splay(Find_kth(r+2),rt); 50 int x=ch[ch[rt][1]][0];Mark_add(x,v); 51 } 52 void Reverse(int l,int r) 53 { Splay(Find_kth(l),0);Splay(Find_kth(r+2),rt); 54 int x=ch[ch[rt][1]][0];Mark_rev(x); 55 } 56 int Query_max(int l,int r) 57 { Splay(Find_kth(l),0);Splay(Find_kth(r+2),rt); 58 return mx[ch[ch[rt][1]][0]]; 59 } 60 int main() 61 { n=read(), m=read();int k,l,r,v,i; 62 rt=Building(0,n+1,rt=0); 63 for (i=1;i<=m;i++) 64 { k=read(); 65 if (k==1){l=read(),r=read(),v=read(),Add(l,r,v);} 66 if (k==2){l=read(),r=read(),Reverse(l,r);} 67 if (k==3){l=read(),r=read(),printf("%d\n",Query_max(l,r));} 68 } 69 return 0; 70 }
就是有点大常数不开心。
以上是关于Bzoj 1251: 序列终结者 (Splay 模板题)的主要内容,如果未能解决你的问题,请参考以下文章