GSS6 4487. Can you answer these queries VI splay
GSS6 Can you answer these queries VI
给出一个数列,有以下四种操作:
I x y: 在位置x插入y。
D x : 删除位置x上的元素。
R x y: 把位置x用y取替。
Q x y: 输出区间[x,y]的最大字段和。
分析:
其实这题是BZOJ 1500 [NOI2005]维修数列这题的简化版。
使用splay来做非常简单。
我的做法增加一个虚拟节点在数列的最开始处,增加两个虚拟节点在最后,这是为了方便在数列最后插入的操作。
splay网上的资料比较多,其实splay比sbt、avl都简单。这里有我的一份总结,并且有一些资料: splay总结
囧,我写的splay太慢了,最后上网搜了一个IO外挂才过了。
#include <set> #include <map> #include <list> #include <cmath> #include <queue> #include <stack> #include <string> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; #define debug puts("here") #define rep(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define REP(i,a,b) for(int i=a;i<=b;i++) #define foreach(i,vec) for(unsigned i=0;i<vec.size();i++) #define pb push_back #define RD(n) scanf("%d",&n) #define RD2(x,y) scanf("%d%d",&x,&y) #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w) #define All(vec) vec.begin(),vec.end() #define MP make_pair #define PII pair<int,int> #define PQ priority_queue #define cmax(x,y) x = max(x,y) #define cmin(x,y) x = min(x,y) #define Clear(x) memset(x,0,sizeof(x)) /* #pragma comment(linker, "/STACK:1024000000,1024000000") int size = 256 << 20; // 256MB char *p = (char*)malloc(size) + size; __asm__("movl %0, %%esp\n" :: "r"(p) ); */ /******** program ********************/ const int MAXN = 210005; const int INF = 1e9; int ch[MAXN][2],fa[MAXN],sz[MAXN],root,tot; int sum[MAXN],val[MAXN]; int lmax[MAXN],rmax[MAXN],mmax[MAXN]; int a[MAXN]; #define lx ch[x][0] #define rx ch[x][1] #define px fa[x] #define ly ch[y][0] #define ry ch[y][1] #define py fa[y] #define lz ch[z][0] #define rz ch[z][1] #define pz fa[z] #define rt ch[root][1] #define lrt ch[rt][0] #define rrt ch[rt][1] // 调试 void dfs(int x){ if(x){ int a = ch[x][0]; int b = ch[x][1]; dfs(a); printf("x: %3d %3d %3d ",x,a,b); printf("val: %3d\n",val[x]); dfs(b); } } void gdb(){ puts("\n---------------------"); dfs(root); puts("---------------------\n"); } inline void update(int x){ if(!x)return; sz[x] = sz[lx]+sz[rx]+1; sum[x] = sum[lx]+sum[rx]+val[x]; lmax[x] = max( lmax[lx] , sum[lx]+val[x]+max(0,lmax[rx]) ); rmax[x] = max( rmax[rx] , sum[rx]+val[x]+max(0,rmax[lx]) ); mmax[x] = max( mmax[lx] , mmax[rx] ); mmax[x] = max( mmax[x] , max(0,lmax[rx])+val[x]+max(0,rmax[lx]) ); } inline int sgn(int x){ return ch[px][1]==x; } inline void setc(int y,int d,int x){ ch[y][d] = x; px = y; } inline void rot(int x,int d){ int y = px; int z = py; setc(y,!d,ch[x][d]); if(z) setc(z,sgn(y),x); fa[x] = z; setc(x,d,y); update(y); } inline void splay(int x,int goal=0){ if(!x)return; while(px!=goal){ int y = px; int z = py; if(z==goal){ rot(x,!sgn(x)); break; } if(lz==y){ if(ly==x) rot(y,1),rot(x,1); else rot(x,0),rot(x,1); } else{ if(ry==x) rot(y,0),rot(x,0); else rot(x,1),rot(x,0); } } update(x); if(goal==0) root = x; } inline void newNode(int &x,int y,int v){ x = ++ tot; sz[x] = 1; ch[x][0] = ch[x][1] = 0; val[x] = sum[x] = lmax[x] = rmax[x] = mmax[x] = v; fa[x] = y; } inline void build(int &x,int y,int l,int r){ if(l>r) return; int mid = (l+r)>>1; newNode(x,y,a[mid]); build(lx,x,l,mid-1); build(rx,x,mid+1,r); update(x); } inline int getKth(int x,int k){ while( sz[lx]+1 != k ){ if(k<=sz[lx])x = lx; else{ k -= sz[lx]+1; x = rx; } } return x; } inline void splay(int x,int y,int ok){ splay( getKth(root,x) ); splay( getKth(root,y) , root ); } inline void Int(int &num){ char in; bool neg=false; while(((in=getchar()) > '9' || in<'0') && in!='-') ; if(in=='-'){ neg=true; while((in=getchar()) >'9' || in<'0'); } num=in-'0'; while(in=getchar(),in>='0'&&in<='9') num*=10,num+=in-'0'; if(neg) num=0-num; } char Char() { char res; while (res = getchar(), !isalpha(res)); return res; } char s[MAXN<<2]; int cur; inline int Int(){ int ans = 0; bool ok = 0 , f = 0; for(;s[cur];cur++){ if(s[cur]==' '){ if(f)break; continue; }f = true; if(s[cur]=='-')ok = true; else ans = ans*10+s[cur]-'0'; } if(ok)ans = -ans; return ans; } int main(){ #ifndef ONLINE_JUDGE freopen("sum.in","r",stdin); //freopen("sum.out","w",stdout); #endif int n,m,x,y; char op; RD(n); rep1(i,n) Int(a[i]); lmax[0] = mmax[0] = rmax[0] = -INF; a[++n] = INF; // 补一个虚拟节点,方便在最后插入 newNode(root,0,-INF); newNode(ch[root][1],root,INF); update(rt); update(root); build(lrt,rt,1,n); update(rt); update(root); RD(m); while(m--){ op = Char(); Int(x); if(op=='I'){ Int(y); splay(x,x+1,0); newNode(lrt,rt,y); update(rt); update(root); }else if(op=='D'){ splay(x,x+2,0); fa[lrt] = 0; lrt = 0; }else if(op=='R'){ Int(y); splay(x,x+2,0); fa[lrt] = 0; lrt = 0; newNode(lrt,rt,y); }else{ Int(y); splay(x,y+2,0); printf("%d\n",mmax[lrt]); } } return 0; }