●个人感觉:
- 代码长;
- 函数多;
- (很套路);
- (很强的Splay,无愧于“区间王”)
●NOI2005维修数列
- 一个可以当模板学习的题,包含了众多操作(函数):
- 区间插入,删除,更新,翻转,询问信息以及”回收空间”(名字很刚)等。
- update()pushdown() rotate() splay() build() find() split() insert() rec() erase() query() rever() modify()还有main()
- 建议初学Splay者打一打;
- 代码:
-
I'm here!
1 #include<queue> 2 #include<cmath> 3 #include<cstdio> 4 #include<cstring> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #define inf 1000000000 9 #define N 1000005 10 using namespace std; 11 int read() 12 { 13 int x=0,f=1;char ch=getchar(); 14 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 15 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 16 return x*f; 17 } 18 int n,m,rt,cnt,k,len,val; char ch[10]; 19 int a[N],id[N],fa[N],c[N][2]; 20 int sum[N],siz[N],v[N],mx[N],lx[N],rx[N]; 21 bool tag[N],rev[N]; 22 queue<int> q; 23 void update(int x) 24 { 25 int l=c[x][0],r=c[x][1]; 26 sum[x]=sum[l]+sum[r]+v[x]; 27 siz[x]=siz[l]+siz[r]+1; 28 mx[x]=max(mx[l],mx[r]); 29 mx[x]=max(mx[x],rx[l]+v[x]+lx[r]); 30 lx[x]=max(lx[l],sum[l]+v[x]+lx[r]); 31 rx[x]=max(rx[r],sum[r]+v[x]+rx[l]); 32 } 33 void pushdown(int x) 34 { 35 int l=c[x][0],r=c[x][1]; 36 if(tag[x]) 37 { 38 rev[x]=tag[x]=0; 39 if(l) tag[l]=1,v[l]=v[x],sum[l]=v[l]*siz[l]; 40 if(r) tag[r]=1,v[r]=v[x],sum[r]=v[r]*siz[r]; 41 if(v[x]>=0) 42 { 43 if(l) lx[l]=rx[l]=mx[l]=sum[l]; 44 if(r) lx[r]=rx[r]=mx[r]=sum[r]; 45 } 46 else 47 { 48 if(l)lx[l]=rx[l]=0,mx[l]=v[x]; 49 if(r)lx[r]=rx[r]=0,mx[r]=v[x]; 50 } 51 } 52 if(rev[x]) 53 { 54 rev[x]^=1;rev[l]^=1;rev[r]^=1; 55 swap(lx[l],rx[l]);swap(lx[r],rx[r]); 56 swap(c[l][0],c[l][1]);swap(c[r][0],c[r][1]); 57 } 58 } 59 void rotate(int x,int &k)//Ðýת£¨µ¥£© 60 { 61 int y=fa[x],z=fa[y]; 62 int l=(x!=c[y][0]),r=l^1; 63 if(y==k) k=x; 64 else c[z][y!=c[z][0]]=x; 65 fa[x]=z; fa[y]=x; fa[c[x][r]]=y; 66 c[y][l]=c[x][r]; c[x][r]=y; 67 update(y); update(x); 68 } 69 void splay(int x,int &k) 70 { 71 int y,z; 72 while(x!=k) 73 { 74 y=fa[x],z=fa[y]; 75 if(y!=k) 76 { 77 if(c[y][0]==x^c[z][0]==y) rotate(x,k); 78 else rotate(y,k); 79 } 80 rotate(x,k); 81 } 82 } 83 void build(int l,int r,int f) 84 { 85 if(l>r) return; 86 int mid=l+r>>1,now=id[mid],last=id[f]; 87 if(l==r) 88 { 89 sum[now]=a[l]; 90 siz[now]=1; 91 tag[now]=rev[now]=0; 92 if(a[l]>=0)lx[now]=rx[now]=mx[now]=a[l]; 93 else lx[now]=rx[now]=0,mx[now]=a[l]; 94 } 95 build(l,mid-1,mid);build(mid+1,r,mid); 96 v[now]=a[mid]; 97 fa[now]=last; 98 c[last][mid>=f]=now; 99 update(now); 100 } 101 int find(int k,int x) 102 { 103 pushdown(k); 104 if(siz[c[k][0]]+1==x) return k; 105 if(siz[c[k][0]]>=x) return find(c[k][0],x); 106 else return find(c[k][1],x-siz[c[k][0]]-1); 107 } 108 int split(int k,int len) 109 { 110 int x=find(rt,k),y=find(rt,k+len+1); 111 splay(x,rt);splay(y,c[x][1]); 112 return c[y][0]; 113 } 114 void insert(int k,int len) 115 { 116 for(int i=1;i<=len;i++) 117 if(!q.empty()) id[i]=q.front(),q.pop(); 118 else id[i]=++cnt; 119 for(int i=1;i<=len;i++) a[i]=read(); 120 build(1,len,0); 121 int x=id[1+len>>1]; 122 int z=find(rt,k+1),y=find(rt,k+2);//µÚһλΪ-inf 123 splay(z,rt); splay(y,c[z][1]); 124 fa[x]=y; c[y][0]=x; 125 update(y);update(fa[y]); 126 } 127 void rec(int x) 128 { 129 if(!x) return; 130 int l=c[x][0],r=c[x][1]; 131 rec(l); rec(r); 132 q.push(x); 133 fa[x]=c[x][0]=c[x][1]=0; 134 tag[x]=rev[x]=0; 135 } 136 void erase(int k,int len) 137 { 138 int x=split(k,len),y=fa[x]; 139 rec(x); c[y][0]=0; 140 update(y);update(fa[y]); 141 } 142 void query(int k,int len) 143 { 144 int x=split(k,len); 145 printf("%d\n",sum[x]); 146 } 147 void rever(int k,int len)//Çø¼ä·×ª 148 { 149 int x=split(k,len),y=fa[x]; 150 if(!tag[x]) 151 { 152 rev[x]^=1; 153 swap(lx[x],rx[x]); 154 swap(c[x][0],c[x][1]); 155 update(y);update(fa[y]); 156 } 157 } 158 void modify(int k,int len,int val) 159 { 160 int x=split(k,len),y=fa[x]; 161 tag[x]=1; v[x]=val; 162 sum[x]=v[x]*siz[x]; 163 if(v[x]>=0) lx[x]=rx[x]=mx[x]=sum[x]; 164 else lx[x]=rx[x]=0,mx[x]=v[x]; 165 update(y);update(fa[y]); 166 } 167 int main() 168 { 169 n=read();m=read(); 170 mx[0]=a[1]=a[n+2]=-inf; id[1]=1; id[n+2]=n+2; 171 for(int i=2;i<=n+1;i++) a[i]=read(),id[i]=i; 172 build(1,n+2,0); 173 rt=n+3>>1; cnt=n+2; 174 while(m-->0) 175 { 176 scanf("%s",ch); 177 if(ch[0]!='M'||ch[2]!='X') k=read(),len=read(); 178 if(ch[0]=='I') insert(k,len); 179 if(ch[0]=='D') erase(k,len); 180 if(ch[0]=='R') rever(k,len); 181 if(ch[0]=='G') query(k,len); 182 if(ch[0]=='M') 183 { 184 if(ch[2]=='X')printf("%d\n",mx[rt]); 185 else val=read(),modify(k,len,val); 186 } 187 } 188 return 0; 189 }