一个序列,四中操作,在x前插入y;删除位置x的数;把位置x的数改成y;查询区间[x,y]的最大子段和。算是维护数列的简化版吧,但时间卡的要死=...输入挂+输出挂都用上了才勉强卡过去....
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cstring> using namespace std; typedef int ll; const int maxn=200000+10000; int a[maxn]; int root,tot,n,m; int p,q,tt,t,k,r; inline int getint() { int res; char ch; bool neg; while (ch = getchar(), !isdigit(ch) && ch != '-') ; if (ch == '-') { res = 0; neg = true; } else { res = ch - '0'; neg = false; } while (ch = getchar(), isdigit(ch)) res = res * 10 + ch - '0'; return neg ? -res : res; } inline char CHAR() { char res; while (res = getchar(), !isalpha(res)) ; return res; } inline void printf_(int num){ bool flag=false; if(num<0){ putchar('-'); num=-num; } int ans[10],top=0; while(num!=0){ ans[top++]=num%10; num/=10; } if(top==0) putchar('0'); for(int i=top-1;i>=0;i--){ char ch=ans[i]+'0'; putchar(ch); } putchar('\n'); } struct splaytree { ll key[maxn],sub[maxn],suff[maxn],pref[maxn],sum[maxn]; int pre[maxn],ch[maxn][2]; int stk[maxn]; int top; int size[maxn]; inline void pushup(int r) { if (r==0) return; size[r]=size[ch[r][0]]+1+size[ch[r][1]]; sum[r]=sum[ch[r][0]]+key[r]+sum[ch[r][1]]; pref[r]=max(pref[ch[r][0]],sum[ch[r][0]]+key[r]+max(0,pref[ch[r][1]])); suff[r]=max(suff[ch[r][1]],sum[ch[r][1]]+key[r]+max(0,suff[ch[r][0]])); sub[r]=max(0,suff[ch[r][0]])+key[r]+max(0,pref[ch[r][1]]); sub[r]=max(sub[r],max(sub[ch[r][0]],sub[ch[r][1]])); } inline void rotate(int x,int kind) { int y=pre[x]; ch[y][!kind]=ch[x][kind]; pre[ch[x][kind]]=y; if (pre[y]) { ch[pre[y]][ch[pre[y]][1]==y]=x; } pre[x]=pre[y]; ch[x][kind]=y; pre[y]=x; pushup(y); } inline void splay(int x,int tgt) { while(pre[x]!=tgt) { int y=pre[x]; if (pre[pre[x]]==tgt) { rotate(x,ch[pre[x]][0]==x); } else { int kind=ch[pre[y]][0]==y; if (ch[y][kind]==x) { rotate(x,kind^1); rotate(x,kind); } else { rotate(y,kind); rotate(x,kind); } } } pushup(x); if (tgt==0) root=x; } inline int select(int k,int tgt) { int rt=root; while(true) { if (k<=size[ch[rt][0]]) rt=ch[rt][0]; else if (k==size[ch[rt][0]]+1) break; else k-=(size[ch[rt][0]]+1),rt=ch[rt][1]; } if (tgt>=0) splay(rt,tgt); return rt; } inline void newnode(int &r,int father,ll k) { // if (top) // { // r=stk[top--]; // } // else r=++tot; r=++tot; pre[r]=father; size[r]=1; key[r]=k; sum[r]=suff[r]=pref[r]=sub[r]=k; ch[r][0]=ch[r][1]=0; } inline void build(int l,int r,int &x,int rt) { if (l>r) return; int m=(l+r)>>1; newnode(x,rt,a[m]); build(l,m-1,ch[x][0],x); build(m+1,r,ch[x][1],x); pushup(x); } inline void init() { tot=root=0; top=0; newnode(root,0,-(1<<30)); newnode(ch[root][1],root,-(1<<30)); suff[0]=pref[0]=sub[0]=-(1<<30); suff[1]=pref[1]=sub[1]=-(1<<30); suff[2]=pref[2]=sub[2]=-(1<<30); build(1,n,ch[ch[root][1]][0],ch[root][1]); pushup(ch[root][1]); pushup(root); } inline void insert(int posi,int num) { ll c; select(posi+1,0); select(posi+2,root); int tp; tp=getint(); newnode(ch[ch[root][1]][0],ch[root][1],tp); pushup(ch[root][1]); pushup(root); } inline void del(int posi) { select(posi,0); select(posi+2,root); int k=ch[ch[root][1]][0]; // recover(k); pre[k]=0; ch[ch[root][1]][0]=0; pushup(ch[root][1]); pushup(root); } inline void recover(int r) { if (!r) return; stk[++top]=r; recover(ch[r][0]); recover(ch[r][1]); } inline int Max_sum(int l,int r) { select(l,0); select(r+2,root); return sub[ch[ch[root][1]][0]]; } inline void modify(int posi,int x) { select(posi+1,0); key[root]=x; pushup(root); } }spt; char cmd[30]; int x,y,z; ll c; int main() { //freopen("in.txt","r",stdin); n=getint(); for (int i=1; i<=n; i++) { a[i]=getint(); } spt.init(); m=getint(); char cc; for (int i=1; i<=m; i++) { // cout<<ch[0][0]<<"---"<<ch[0][1]<<"--"<<pre[0]<<"hit----\n"; cc=CHAR(); if (cc=='I') { x=getint(); spt.insert(x-1,1); } else if (cc=='Q') { x=getint(); y=getint(); int ans=spt.Max_sum(x,y); printf_(ans); // printf("%d\n",ans); } else if (cc=='R') { x=getint(); y=getint(); spt.modify(x,y); } else if (cc=='D') { x=getint(); spt.del(x); } } return 0; }