Splay(区间操作)伪模板 [BZOJ][1500][NOI2005]维修数列
#include<bits/stdc++.h> #include<bits/stdtr1c++.h> using namespace std; const int MAXN=1e6+2333; int n,m; int a[MAXN]; namespace Splay { #define OTZ (ch[ch[root][1]][0]) int root,cnt1; int st[MAXN],cnt2; int ch[MAXN][2],fa[MAXN],siz[MAXN]; int key[MAXN],sum[MAXN]; int lx[MAXN],rx[MAXN],mx[MAXN]; int rev[MAXN],same[MAXN]; void New_Node(int &x,int p,int val) { if (cnt2) x=st[cnt2--]; else x=++cnt1; fa[x]=p,ch[x][0]=ch[x][1]=0,siz[x]=1; key[x]=sum[x]=lx[x]=rx[x]=mx[x]=val; rev[x]=same[x]=0; } void update_rev(int x) { if (!x) return; swap(ch[x][0],ch[x][1]); swap(lx[x],rx[x]); rev[x]^=1; } void update_same(int x,int val) { if (!x) return; key[x]=val; sum[x]=val*siz[x]; lx[x]=rx[x]=mx[x]=max(key[x],sum[x]); same[x]=1; } void push_up(int x) { siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+key[x]; lx[x]=max(lx[ch[x][0]],sum[ch[x][0]]+key[x]+max(0,lx[ch[x][1]])); rx[x]=max(rx[ch[x][1]],sum[ch[x][1]]+key[x]+max(0,rx[ch[x][0]])); mx[x]=max(0,rx[ch[x][0]])+key[x]+max(0,lx[ch[x][1]]); mx[x]=max(mx[x],max(mx[ch[x][0]],mx[ch[x][1]])); } void push_down(int x) { if (!x) return; if (rev[x]) update_rev(ch[x][0]),update_rev(ch[x][1]),rev[x]=0; if (same[x]) update_same(ch[x][0],key[x]),update_same(ch[x][1],key[x]),same[x]=0; } void build_tree(int &x,int l,int r,int p) { if (l>r) return; int mid=l+r>>1; New_Node(x,p,a[mid]); build_tree(ch[x][0],l,mid-1,x); build_tree(ch[x][1],mid+1,r,x); push_up(x); } void rotate(int x,int &k) { int y=fa[x],z=fa[y],d=(ch[y][1]==x); if (y!=k) ch[z][ch[z][1]==y]=x; else k=x; fa[x]=z; ch[y][d]=ch[x][d^1],fa[ch[x][d^1]]=y; ch[x][d^1]=y,fa[y]=x; push_up(y),push_up(x); } void MIDD(int x,int &k) { if (fa[x]!=k) push_down(fa[fa[x]]); push_down(fa[x]),push_down(x); rotate(x,k); } void splay(int x,int &k) { for (int y; (y=fa[x])&&x!=k; MIDD(x,k)) if (y!=k) MIDD((ch[y][0]==x)^(ch[fa[y]][0]==y) ? x:y,k); } int kth(int x,int k) { push_down(x); if (siz[ch[x][0]]+1==k) return x; else if (siz[ch[x][0]]>=k) return kth(ch[x][0],k); else return kth(ch[x][1],k-siz[ch[x][0]]-1); } void Insert(int pl,int num) { for (int i=1; i<=num; i++) scanf("%d",&a[i]); splay(kth(root,pl+1),root); splay(kth(root,pl+2),ch[root][1]); build_tree(OTZ,1,num,ch[root][1]); push_up(ch[root][1]); push_up(root); } void Recycle_Node(int x) { if (!x) return; st[++cnt2]=x; Recycle_Node(ch[x][0]); Recycle_Node(ch[x][1]); } void Delt(int pl,int num) { splay(kth(root,pl),root); splay(kth(root,pl+num+1),ch[root][1]); Recycle_Node(OTZ); fa[OTZ]=0; OTZ=0; push_up(ch[root][1]); push_up(root); } void Make_Same(int pl,int num,int val) { splay(kth(root,pl),root); splay(kth(root,pl+num+1),ch[root][1]); update_same(OTZ,val); push_up(ch[root][1]); push_up(root); } void Reverse(int pl,int num) { splay(kth(root,pl),root); splay(kth(root,pl+num+1),ch[root][1]); update_rev(OTZ); push_up(ch[root][1]); push_up(root); } int Get_Sum(int pl,int num) { splay(kth(root,pl),root); splay(kth(root,pl+num+1),ch[root][1]); return sum[OTZ]; } int Get_Max(int pl,int num) { splay(kth(root,pl),root); splay(kth(root,pl+num+1),ch[root][1]); return mx[OTZ]; } void Initialization() { New_Node(root,0,-233); New_Node(ch[root][1],root,-233); for (int i=1; i<=n; i++) scanf("%d",&a[i]); build_tree(OTZ,1,n,ch[root][1]); push_up(ch[root][1]); push_up(root); mx[0]=-0x3f3f3f3f; } #undef OTZ } using namespace Splay; int main() { scanf("%d%d",&n,&m); Initialization(); char opt[233]; int x,y,z; while (m--) { scanf("%s",opt); if (strcmp(opt,"INSERT")==0) scanf("%d%d",&x,&y),Insert(x,y); else if (strcmp(opt,"DELETE")==0) scanf("%d%d",&x,&y),Delt(x,y); else if (strcmp(opt,"MAKE-SAME")==0) scanf("%d%d%d",&x,&y,&z),Make_Same(x,y,z); else if (strcmp(opt,"REVERSE")==0) scanf("%d%d",&x,&y),Reverse(x,y); else if (strcmp(opt,"GET-SUM")==0) scanf("%d%d",&x,&y),printf("%d\n",Get_Sum(x,y)); else if (strcmp(opt,"MAX-SUM")==0) printf("%d\n",Get_Max(1,siz[root]-2)); } return 0; }