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 模板题)的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1251序列终结者 splay

BZOJ1251 序列终结者(Splay平衡树)(占位)

BZOJ1251: 序列终结者

BZOJ1251: 序列终结者

1251. 序列终结者平衡树-splay

bzoj 1251: 序列终结者 2011-12-20