Test instructions
gives a sequence of n length and M operations;
Output an answer to each 5,6 operation;
Data range eaten by BZ:
You can think of at least 1 numbers in a sequence at any given moment;
The input data must be correct, that is, the number of the specified position must exist in the sequence;
50% of the data, at any time the number of columns in a maximum of 30 000;
100% of the data, at any time the number of columns in a maximum of 500 000;
100% of the data, any time in the sequence of any number of numbers in [-1 000, 1 000];
100% of the data, M≤20 000, the total number of inserted numbers not more than 4 000 000.
Exercises
After writing this question, I feel that life has no regrets;
First analyze the topic;
The operation involves the addition and deletion of the interval, which is obviously a splay;
3,4 operation is the change of interval, to maintain the delay mark for such large data range;
5,6 operation is output, nothing to say;
Then look at the data range, the sequence length of not more than 500 000, the number of inserts not more than 4 000 000;
I am a konjac konjac unexpectedly directly open large array on it, and did not consider the problem of memory recovery;
Then WA had a half-day and could not make mistakes on the racket;
So the array opened small why not re ah!!
I'm driving 5 times times as much memory on Cena a ...
↑ so memory to recycle ↑
In order to facilitate a point to the two sides to take the interval, I added two at both ends of useless nodes;
Maintenance 6 Inquiry is to maintain the maximum value to the left of the maximum value and the middle of the maximum value, respectively, with lm,rm,ma expression;
But because two useless nodes, let the problem become somewhat complicated;
If the value of the useless node is 0, then when the entire interval is negative, the answer is 0, and the title must take a maximum negative number;
If the value of the useless node is negative infinity, there may be a problem while maintaining sum, and the negative infinity in int is added to infinity (laughter);
So I recorded a IGN tag that was assigned to two useless nodes and 0 nodes;
is to ignore their values when seeking the maximum value;
Then say the question of the mark;
3 The operation is careful to maintain the interval to 0, if only with the judgment mark is 0 will hang in this;
4 Operation note the pushdown when the current node of the left and right sub-tree has been exchanged, should be exchanged is the subtree of the tree;
Exchange the direct exchange of the left and right sub-tree and LM and RM;
Nothing else to say, Splay realize I opened the structure, but it doesn't matter;
In fact, open structure in addition to the recovery of memory directly memset convenient point is more troublesome;
Bonus pair of data generators one (below);
Code:
#include <stdio.h> #include <string.h> #include <algorithm> #define N 510000#define Lson tr[tr[x].ch[0 ]] #define Rson tr[tr[x].ch[1]] #define which (x) (tr[tr[x].fa].ch[1]==x) using namespace std;struct splay_tree{int val,ch [2],fa,size,sum,lm,rm,ma,cov;bool flag1,flag2,ign;} Tr[n];char str[100];int root,tot,st[n],top;void pushup (int x) {tr[x].sum=lson.sum+rson.sum+tr[x].val;tr[x].size= Lson.size+rson.size+1;tr[x].lm=max (Lson.lm,lson.sum+tr[x].val+max (rson.lm,0)); Tr[x].rm=max (rson.rm,tr[x].val+ Rson.sum+max (lson.rm,0)) Tr[x].ma=max (max (lson.rm,0) + (Tr[x].ign?-0x3f3f3f3f:tr[x].val) +max (rson.lm,0), Max ( lson.ma,rson.ma));} void pushdown (int x) {if (TR[X].FLAG2) {if (tr[x].ch[0]) {lson.flag2=1;lson.val=lson.cov=tr[x].cov;lson.sum=lson.size *tr[x].cov;lson.lm=lson.rm=lson.ma=max (lson.cov,lson.sum);} if (Tr[x].ch[1]) {rson.flag2=1;rson.val=rson.cov=tr[x].cov;rson.sum=rson.size*tr[x].cov;rson.lm=rson.rm=rson.ma= Max (rson.cov,rson.sum);}} else if (TR[X].FLAG1) {Lson.flag1^=1,rson.flag1^=1;swap (lson.ch[0],lSON.CH[1]); swap (lson.lm,lson.rm); swap (rson.ch[0],rson.ch[1]); swap (RSON.LM,RSON.RM); tr[x].flag1=tr[x].flag2=tr[x].cov=0;} int Build (int l,int r,int f) {if (l>r) return 0;int mid= (l+r) >>1,x;if (top) x=st[top--];elsex=++tot;tr[x].fa=f; Tr[x].ch[0]=build (l,mid-1,x); scanf ("%d", &tr[x].val); Tr[x].ch[1]=build (mid+1,r,x); if (l==r) {tr[x].size=1;tr[ X].sum=tr[x].val;tr[x].lm=tr[x].rm=tr[x].ma=tr[x].val;} Elsepushup (x); return x;} void Rotate (int x) {int f=tr[x].fa;bool k=which (x); tr[f].ch[k]=tr[x].ch[!k];tr[tr[x].ch[!k]].fa=f;tr[x].ch[!k]=f;tr [Tr[f].fa].ch[which (f)]=x;tr[x].fa=tr[f].fa;tr[f].fa=x; Pushup (f); Pushup (x);} void splay (int x,int g) {if (!x) return, while (tr[x].fa!=g) {int f=tr[x].fa;if (tr[f].fa==g) {Rotate (x); continue;} if (which (f) ^which (x)) Rotate (x); elserotate (f); Rotate (x);} if (!g) root=x;} int Rank (int x,int k) {if (x==0| | K==0) return 0; Pushdown (x), if (k<=lson.size) return rank (tr[x].ch[0],k), else if (k==lson.size+1) return X;elsereturn rank (tr[x].ch [1],k-lson.size-1);} void Init (int n) {int X;x=ranK (root,1); Splay (x,0); tr[x].ch[0]=++tot;tr[tot].ign=tr[tot].size=1;tr[tot].fa=x;tr[tot].lm=tr[tot].rm=tr[tot].ma=- 0x3f3f3f3f; Pushup (x); X=rank (root,1+n); Splay (x,0); tr[x].ch[1]=++tot;tr[tot].ign=tr[tot].size=1;tr[tot].fa=x;tr[tot].lm=tr[tot].rm=tr[tot].ma=- 0x3f3f3f3f; Pushup (x);} void Getback (int x) {if (!x) return; st[++top]=x; Getback (Tr[x].ch[0]); Getback (tr[x].ch[1]); memset (&tr[x],0,sizeof (Splay_tree));} void Insert () {int p,n,x,y;scanf ("%d%d", &p,&n);p ++;x=rank (root,p); Splay (x,0); Y=rank (root,p+1); Splay (y,x); Tr[y].ch[0]=build (1,n,y); Pushup (y); Pushup (x);} void Delete () {int p,n,x,y;scanf ("%d%d", &p,&n);p ++;x=rank (root,p-1); Splay (x,0); Y=rank (root,p+n); Splay (Y,X); Getback (Tr[y].ch[0]); tr[y].ch[0]=0; Pushup (y); Pushup (x);} void Update () {int p,n,v,x,y,t;scanf ("%d%d%d", &p,&n,&v);p ++;x=rank (root,p-1); Splay (x,0); Y=rank (root,p+n); Splay (y,x); t=tr[y].ch[0];tr[t].flag2=1;tr[t].val=tr[t].cov=v;tr[t].sum=tr[t].size*v;tr[t].lm=tr[t].rm=tr[t].ma =max (v,tr[t].sum); Pushup (y); Pushup (x);} VoID Reverse () {int p,n,x,y,t;scanf ("%d%d", &p,&n);p ++;x=rank (root,p-1); Splay (x,0); Y=rank (root,p+n); Splay (y,x); T=tr[y].ch[0];tr[t].flag1^=1;swap (tr[t].ch[0],tr[t].ch[1]); swap (TR[T].LM,TR[T].RM); Pushup (y); Pushup (x);} void Getsum () {int p,n,x,y,t;scanf ("%d%d", &p,&n);p ++;x=rank (root,p-1); Splay (x,0); Y=rank (root,p+n); Splay (y,x); t=tr[y].ch[0];p rintf ("%d\n", tr[t].sum); Pushup (y); Pushup (x);} void Getmax () {printf ("%d\n", tr[root].ma);} int main () {int n,m,i,j,k,x,y;scanf ("%d%d", &n,&m); tr[0].ign=1;tr[0].lm=tr[0].rm=tr[0].ma=-0x3f3f3f3f;root =build (1,n,0), Init (n), for (i=1;i<=m;i++) {scanf ("%s", str), switch (str[2]) {case ' s ': Insert (); Break;case ' L ':D Elete (); Break;case ' K ': Update (); Break;case ' V ': Reverse (); Break;case ' T ': getsum (); Break;case ' X ': Getmax ();}} return 0;}
Data generators:
#include <stdio.h> #include <string.h> #include <algorithm> #define RANDOM rand ()%2000-1000using Namespace Std;typedef Long Long ll;int main () {Srand (Time (NULL)); int N=300,m=10;int i,j,k,x,y;printf ("%d%d\n", n,m); for (i=1;i<=n;i++) printf ("%d", Random);p UTS (""); for (i=1;i<=m;i++) {K=rand ()%6;if (!n) return 0;x=rand ()%n+1;y= Rand ()% (n-x+1) +1;switch (k) {case 0:puts ("INSERT");p rintf ("%d%d", X, Y), for (j=1;j<=y;j++) printf ("%d", Random); Puts (""); N+=y;break;case 1:puts ("DELETE");p rintf ("%d%d\n", x, y), N-=y;break;case 2:puts ("Make-same");p rintf ("%d%d D\n ", X,y,random), Break;case 3:puts (" REVERSE ");p rintf ("%d%d\n ", x, y), Break;case 4:puts (" Get-sum ");p rintf ("%d%d\n ", x, y); Break;case 5:puts ("Max-sum"); break;}} return 0;}
BZOJ-1500 Maintenance Series