bzoj1500[NOI2005]维修数列
一直心心念念着的splay模板。终于写了。
写了半个下午,然后半个晚上重构,半个晚上debug。
终于A了。。
码力真是弱的可怕。
二十分钟找到第一个bug,kth时忘了down。
然后剩下的一整个晚上才发现第2个bug,且是在同一个地方,应该是先down再判断找没找到。
又花了十分钟找到第三个bug,先del再把它设为0,都为0了还del个鬼啊。。。
以前写不出题基本上上都是完全没思路,然后现在完全没思路的多,还常碰到有想法但写不出来或者写起来非常难受的,码力真的需要提升啊,智商已经低了,码力还这么低岂不是药丸。
唯一一点欣慰是一开始写了近300慢慢改到了不到200。
只是今天学数学的目标又泡汤了。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cmath>
const int N=500007;
typedef long long LL;
using namespace std;
int root,n,a[N],m;
char op[20];
template<typename T>void read(T &x) {
char ch=getchar(); T f=1; x=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
queue<int>que;
int v[N],sz[N],flip[N],lz[N],lzz[N],p[N],ch[N][2],ll[N],rr[N],mm[N],sum[N];
#define lc ch[x][0]
#define rc ch[x][1]
int ins() {int x=que.front(); que.pop(); return x;}
void del(int x) {
if(lc) del(lc);
lz[x]=flip[x]=0;
que.push(x);
if(rc) del(rc);
}
void schange(int x,int vv) {
v[x]=lzz[x]=vv;
lz[x]=1; flip[x]=0;
sum[x]=sz[x]*vv;
if(vv>=0) ll[x]=rr[x]=mm[x]=sum[x];
else ll[x]=rr[x]=0,mm[x]=vv;
}
void rever(int x) {
swap(ll[x],rr[x]);
flip[x]^=1;
}
void update(int x) {
sz[x]=sz[lc]+sz[rc]+1;
sum[x]=sum[lc]+sum[rc]+v[x];
ll[x]=max(ll[lc],sum[lc]+v[x]+ll[rc]);
rr[x]=max(rr[rc],sum[rc]+v[x]+rr[lc]);
mm[x]=rr[lc]+v[x]+ll[rc];
if(lc) mm[x]=max(mm[lc],mm[x]);
if(rc) mm[x]=max(mm[rc],mm[x]);
}
void down(int x) {
if(lz[x]) {
if(lc) schange(lc,lzz[x]);
if(rc) schange(rc,lzz[x]);
lz[x]=0;
}
if(flip[x]) {
if(lc) rever(lc);
if(rc) rever(rc);
swap(lc,rc);
flip[x]=0;
}
}
void rotate(int x) {
int y=p[x],z=p[y],l=(x==ch[y][1]),r=l^1;
if(z) ch[z][y==ch[z][1]]=x; p[x]=z;
ch[y][l]=ch[x][r]; p[ch[x][r]]=y;
ch[x][r]=y; p[y]=x;
update(y); update(x);
}
void splay(int x,int FA) {
static int g[N],top=0,tp;
for(tp=x;tp!=FA;tp=p[tp]) g[++top]=tp;
while(top) down(g[top--]);
for(;p[x]!=FA;rotate(x)) {
int y=p[x],z=p[y];
if(z!=FA)
((x==ch[y][1])^(y==ch[z][1]))?rotate(x):rotate(y);
}
if(!FA) root=x;
}
int build(int l,int r) {
if(l>r) return 0;
int mid=((l+r)>>1);
int x=ins(); v[x]=a[mid];
lc=build(l,mid-1); if(lc) p[lc]=x;
rc=build(mid+1,r); if(rc) p[rc]=x;
update(x);
return x;
}
int kth(int k) {
for(int x=root;x;) {
down(x);
if(sz[lc]+1==k) return x;
if(sz[lc]+1<k) k-=(sz[lc]+1),x=rc;
else x=lc;
}
}
void insert(int pos) {
if(!n) return;
int z=build(1,n);
if(!root) root=z,p[z]=0;
else if(pos==0) {
int x=kth(1);
splay(x,0); p[z]=x;
lc=z; update(x);
}
else if(pos==sz[root]) {
int x=kth(sz[root]);
splay(x,0); p[z]=x;
rc=z; update(x);
}
else {
int x=kth(pos);
splay(x,0);
x=kth(pos+1);
splay(x,root); p[z]=x;
lc=z; update(x);
update(root);
}
}
int split(int pos,int &fa,int o) {
if(pos==1&&sz[root]==n) {
if(o) {del(root); root=0; }
return root;
}
if(pos==1) {
int x=kth(pos+n);
splay(x,0);
if(o) {del(lc); lc=0; update(x);}
return lc;
}
else if(pos+n-1==sz[root]){
int x=kth(pos-1);
splay(x,0);
if(o) {del(rc); rc=0; update(x);}
return rc;
}
else {
int x=kth(pos-1); splay(x,0);
x=kth(pos+n); splay(x,root);
if(o) {del(lc); lc=0; update(x); update(root);}
fa=x; return lc;
}
}
int main() {
read(n);
read(m);
for(int i=1;i<N;i++) { que.push(i); sz[i]=1;}
for(int i=1;i<=n;i++) read(a[i]);
root=build(1,n);
while(m--) {
int pos,c,x,fa=0;
int szzz=que.size();
scanf("%s",op);
if(op[2]!='X') {
read(pos); read(n);
}
if(op[0]=='I') {
for(int i=1;i<=n;i++) read(a[i]);
insert(pos);
}
else if(op[0]=='D') x=split(pos,fa,1);
else if(op[2]=='K') {
read(c);
x=split(pos,fa,0);
schange(x,c);
if(fa) update(fa);
update(root);
}
else if(op[0]=='R') {
x=split(pos,fa,0);
rever(x);
if(fa) update(fa);
update(root);
}
else if(op[0]=='G') {
x=split(pos,fa,0);
printf("%d\n",sum[x]);
}
else printf("%d\n",mm[root]);
}
return 0;
}