bzoj1251 -- splay
splay模板题。
用splay维护序列,令splay的中序遍历为这个序列,则在处理[l,r]时,先将l-1旋转到根,再将r+1旋转到根的右子树,那么根的右子树的左子树就是[l,r]了。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 #define N 50010 6 #define INF 2147483647 7 bool b[N]; 8 int i,j,k,m,n,c[N],s[N],a[N],Rt,p[N],ch[N][2],f[N],x,y,z; 9 inline int Get(int x){return ch[f[x]][1]==x;} 10 inline int _Max(int x,int y){return x>y?x:y;} 11 inline void Up(int x){ 12 c[x]=_Max(a[x],_Max(c[ch[x][0]],c[ch[x][1]])); 13 s[x]=s[ch[x][0]]+s[ch[x][1]]+1; 14 } 15 inline void Down(int x){ 16 if(!x)return; 17 if(p[x]){ 18 if(ch[x][0])p[ch[x][0]]+=p[x],c[ch[x][0]]+=p[x],a[ch[x][0]]+=p[x]; 19 if(ch[x][1])p[ch[x][1]]+=p[x],c[ch[x][1]]+=p[x],a[ch[x][1]]+=p[x]; 20 p[x]=0; 21 } 22 if(b[x]){ 23 int t=ch[x][0];ch[x][0]=ch[x][1];ch[x][1]=t; 24 if(ch[x][0])b[ch[x][0]]^=1; 25 if(ch[x][1])b[ch[x][1]]^=1; 26 b[x]=0; 27 } 28 } 29 inline void Rotate(int x){ 30 int y=f[x];bool d=Get(x); 31 ch[f[y]][Get(y)]=x; 32 f[x]=f[y]; 33 ch[y][d]=ch[x][d^1]; 34 f[ch[y][d]]=y; 35 ch[x][d^1]=y; 36 f[y]=x;Up(y); 37 } 38 inline void Splay(int x,int g){ 39 while(f[x]!=g){ 40 Down(f[f[x]]);Down(f[x]);Down(x); 41 if(f[f[x]]){ 42 if(f[f[x]]==g){Rotate(x);break;} 43 Rotate(Get(x)==Get(f[x])?f[x]:x); 44 } 45 Rotate(x); 46 } 47 Up(x); 48 if(!g)Rt=x; 49 } 50 inline int Search(int x){ 51 int u=Rt; 52 Down(u); 53 while(s[ch[u][0]]!=x){ 54 if(s[ch[u][0]]>x)u=ch[u][0];else x-=s[ch[u][0]]+1,u=ch[u][1]; 55 Down(u); 56 } 57 return u; 58 } 59 inline int Build(int l,int r){ 60 if(l>r)return 0; 61 if(l==r)return l; 62 int Mid=l+r>>1; 63 ch[Mid][0]=Build(l,Mid-1); 64 ch[Mid][1]=Build(Mid+1,r); 65 s[Mid]=s[ch[Mid][0]]+s[ch[Mid][1]]+1; 66 f[ch[Mid][0]]=f[ch[Mid][1]]=Mid; 67 Up(Mid); 68 return Mid; 69 } 70 inline void Update(int l,int r,int x){ 71 int u=Search(l-1),v=Search(r+1); 72 Splay(u,0);Splay(v,u); 73 c[ch[v][0]]+=x; 74 p[ch[v][0]]+=x; 75 a[ch[v][0]]+=x; 76 } 77 inline void Reverse(int l,int r){ 78 int u=Search(l-1),v=Search(r+1); 79 Splay(u,0);Splay(v,u); 80 b[ch[v][0]]^=1; 81 } 82 inline int Query(int l,int r){ 83 int u=Search(l-1),v=Search(r+1); 84 Splay(u,0);Splay(v,u); 85 return c[ch[v][0]]; 86 } 87 inline void Init(){ 88 for(int i=1;i<=n+2;i++)s[i]=1; 89 c[0]=a[0]=-INF;c[1]=a[1]=-INF; 90 c[n+2]=a[n+2]=-INF; 91 Rt=Build(1,n+2); 92 ch[0][0]=Rt; 93 } 94 int main() 95 { 96 scanf("%d%d",&n,&m); 97 Init(); 98 while(m--){ 99 scanf("%d",&k); 100 if(k==1)scanf("%d%d%d",&x,&y,&z),Update(x,y,z);else{ 101 scanf("%d%d",&x,&y); 102 if(k==2)Reverse(x,y);else printf("%d\n",Query(x,y)); 103 } 104 } 105 return 0; 106 }bzoj1251