终于打败大boss了,耗时一下午。
应该是splay维护序列题型的巅峰了吧。
这道题不能单纯的开点,因为会MLE,所以要用回收节点的过程。
说一下搞法吧:
1、插入,提取区间,递归建树
2、删除,提取区间,把删去的点用一个栈储存下来
3、修改,提取区间,打个标记
4、翻转,提取区间,打个标记
5、求和、最大连续子段和,维护一下就可以了。
WA点:
这道题不用开longlong,简直是福利
没说数据范围,需要回收内存
标记稍微处理一下就可以了没什么
初始化节点注意把权值赋成-inf,虽然好像没用什么用
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<iostream> #define inf 1010000000 #define maxn 510010 using namespace std; int fa[maxn],ch[maxn][2],w[maxn],size[maxn],sum[maxn],lmax[maxn],rmax[maxn],ans[maxn]; bool rev[maxn]; bool tag[maxn]; int a[maxn]; int st[maxn]; char s[20]; int n,m,T,tot,root,top; int newnode() { int num; if (top) num=st[top--]; else num=++tot; ch[num][0]=ch[num][1]=fa[num]=0; tag[num]=rev[num]=0; size[num]=1; sum[num]=w[num]=rmax[num]=lmax[num]=-inf; return num; } void update(int x) { if (!x) return; size[x]=size[ch[x][0]]+size[ch[x][1]]+1; sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+w[x]; lmax[x]=max(lmax[ch[x][0]],sum[ch[x][0]]+w[x]+max(0,lmax[ch[x][1]])); rmax[x]=max(rmax[ch[x][1]],sum[ch[x][1]]+w[x]+max(0,rmax[ch[x][0]])); ans[x]=max(max(ans[ch[x][0]],ans[ch[x][1]]),max(0,rmax[ch[x][0]])+w[x]+max(0,lmax[ch[x][1]])); } void reverse(int x) { if (!x) return; swap(lmax[x],rmax[x]); swap(ch[x][0],ch[x][1]); rev[x]^=1; } void replace(int x,int d) { if (!x) return; w[x]=d;sum[x]=d*size[x]; lmax[x]=rmax[x]=ans[x]=max(d,d*size[x]); tag[x]=1;rev[x]=0; } void push_down(int x) { if (rev[x]) { if (ch[x][0]) reverse(ch[x][0]); if (ch[x][1]) reverse(ch[x][1]); rev[x]=0; } if (tag[x]) { if (ch[x][0]) replace(ch[x][0],w[x]); if (ch[x][1]) replace(ch[x][1],w[x]); tag[x]=0; } } int dir(int x) { return x==ch[fa[x]][1]; } void rotate(int x) { int y,z,a,b,c; y=fa[x];z=fa[y];b=dir(x);a=ch[x][!b]; if (z==0) root=x; else { c=dir(y);ch[z][c]=x; } fa[x]=z;fa[y]=x;ch[x][!b]=y;ch[y][b]=a; if (a) fa[a]=y; update(y);update(x); } void down(int x) { if (fa[x]) down(fa[x]); push_down(x); } void splay(int x,int i) { down(x); int y,z,b,c; while (fa[x]!=i) { y=fa[x];z=fa[y]; if (z==i) rotate(x); else { b=dir(x);c=dir(y); if (b^c) { rotate(x);rotate(x); } else { rotate(y);rotate(x); } } } } int find_k(int x,int k) { push_down(x); if (size[ch[x][0]]==k-1) return x; if (size[ch[x][0]]>k-1) return find_k(ch[x][0],k); else return find_k(ch[x][1],k-size[ch[x][0]]-1); } void build_tree(int l,int r,int tt) { int mid=(l+r)/2; w[tt]=a[mid]; if (l==r) {sum[tt]=lmax[tt]=rmax[tt]=ans[tt]=w[tt];size[tt]=1;return;} if (l<mid) {ch[tt][0]=newnode();fa[ch[tt][0]]=tt;build_tree(l,mid-1,ch[tt][0]);} if (mid<r) {ch[tt][1]=newnode();fa[ch[tt][1]]=tt;build_tree(mid+1,r,ch[tt][1]);} update(tt); } int Query(int l,int num) { int x=find_k(root,l);splay(x,0); int y=find_k(ch[x][1],num+1);splay(y,x); return sum[ch[y][0]]; } void Insert(int l,int num) { for (int i=1;i<=num;i++) scanf("%d",&a[i]); int x=find_k(root,l+1);splay(x,0); int y=find_k(ch[x][1],1);splay(y,x); ch[y][0]=newnode();fa[ch[y][0]]=y; build_tree(1,num,ch[y][0]); update(y);update(x); } void erase(int x) { if (!x) return; st[++top]=x; if (ch[x][0]) erase(ch[x][0]); if (ch[x][1]) erase(ch[x][1]); } void Delete(int l,int num) { int x=find_k(root,l);splay(x,0); int y=find_k(ch[x][1],num+1);splay(y,x); erase(ch[y][0]); fa[ch[y][0]]=0;ch[y][0]=0; update(y);update(x); } void Reverse(int l,int num) { int x=find_k(root,l);splay(x,0); int y=find_k(ch[x][1],num+1);splay(y,x); reverse(ch[y][0]); update(y);update(x); } void Replace(int l,int num,int d) { int x=find_k(root,l);splay(x,0); int y=find_k(ch[x][1],num+1);splay(y,x); replace(ch[y][0],d); update(y);update(x); } int main() { lmax[0]=rmax[0]=ans[0]=-inf; tot=2;root=1; fa[1]=0;size[1]=2;ch[1][1]=2;w[1]=sum[1]=lmax[1]=rmax[1]=-inf; fa[2]=1;size[2]=1;w[2]=sum[2]=lmax[2]=rmax[2]=-inf; scanf("%d%d",&n,&T); for (int i=1;i<=n;i++) scanf("%d",&a[i]); ch[2][0]=newnode();fa[ch[2][0]]=2; build_tree(1,n,ch[2][0]); update(2);update(1); while (T--) { int x,y,z; scanf("%s",s); if (s[2]=='X') printf("%d\n",ans[root]); if (s[0]=='G') { scanf("%d%d",&x,&y); printf("%d\n",Query(x,y)); } if (s[0]=='I') { scanf("%d%d",&x,&y); Insert(x,y); } if (s[0]=='D') { scanf("%d%d",&x,&y); Delete(x,y); } if (s[0]=='R') { scanf("%d%d",&x,&y); Reverse(x,y); } if (s[4]=='-') { scanf("%d%d%d",&x,&y,&z); Replace(x,y,z); } } return 0; }