题解 SP4487 【GSS6 - Can you answer these queries VI】

Jμdge

2019-10-23 16:15:06

Solution

nan 首先 FHQ 维护动态数组就是了... 剩下的就只是对付询问了...(貌似 GSS8 的思路同上?) 然后咱 FHQ 里面每个节点类似线段树上玩静态数组一样去维护节点就好了,多记录了四个值: $sum , lmax , rmax , mmax$ # Code 不知道简易写法(注释掉的)为什么 挂掉了 ,死活就是过不去. (艹) 可能是 sm 尽管多重考虑之后还是莫名锅了???(强行解释) && 没有压行,手动滑稽,这关键部分的代码不都没压嘛 【雾 顺便提一句,不用开 long long ,以及 FHQ 大小 2e5 就够了 ``` //by Judge #include<iostream> #include<cstdio> using namespace std; const int M=2e5+23; #ifndef Judge #define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) #endif char buf[1<<21],*p1=buf,*p2=buf; inline int Max(int x,int y){return x>y?x:y;} inline int read(){ int x=0,f=1; char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } inline char cread(){ char c=getchar(); while(!isalpha(c)) c=getchar(); return c; } char sr[1<<21],z[20];int C=-1,Z; inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} inline void print(int x){ if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x; while(z[++Z]=x%10+48,x/=10); while(sr[++C]=z[Z],--Z);sr[++C]='\n'; } int n,m; namespace FHQTreap{ int root,cnt; #define ls t[now].ch[0] #define rs t[now].ch[1] struct Node { int val,key,sz,lm,rm,mm,sm,ch[2]; Node(){} Node(int x,int r,int a,int b){ key=r,sz=1,lm=rm=Max(val=sm=mm=x,0),ch[0]=a,ch[1]=b; } } t[M]; inline int Rand() { static signed seed=703; return seed=signed(seed*48271LL%(~0u>>1)); } inline int newnode(int x){ return t[++cnt]=Node(x,Rand(),0,0),cnt; } inline void update(int now){ t[now]=Node(t[now].val,t[now].key,ls,rs); if(ls&&rs){ t[now].sm+=t[ls].sm+t[rs].sm,t[now].sz+=t[ls].sz+t[rs].sz; t[now].lm=Max(t[ls].lm,Max(t[ls].sm+t[now].lm,t[ls].sm+t[now].val+t[rs].lm)); t[now].rm=Max(t[rs].rm,Max(t[rs].sm+t[now].rm,t[rs].sm+t[now].val+t[ls].rm)); t[now].mm=Max(Max(t[ls].mm,t[rs].mm),t[ls].rm+t[now].val+t[rs].lm); } else if(ls){ t[now].sm+=t[ls].sm,t[now].sz+=t[ls].sz; t[now].lm=Max(t[ls].lm,t[ls].sm+t[now].lm); t[now].rm=Max(t[now].rm,t[now].val+t[ls].rm); t[now].mm=Max(t[ls].mm,t[now].val+t[ls].rm); } else if(rs){ t[now].sm+=t[rs].sm,t[now].sz+=t[rs].sz; t[now].rm=Max(t[rs].rm,t[rs].sm+t[now].rm); t[now].lm=Max(t[now].lm,t[now].val+t[rs].lm); t[now].mm=Max(t[rs].mm,t[now].val+t[rs].lm); } /* if(ls){ t[now].mm=Max(Max(t[ls].mm,t[now].mm),t[now].lm+t[ls].rm), t[now].lm=Max(t[ls].lm,t[ls].sm+t[now].lm), t[now].rm=Max(t[now].rm,t[now].sm+t[ls].rm),t[now].sm+=t[ls].sm; } if(rs){ t[now].mm=Max(Max(t[rs].mm,t[now].mm),t[rs].lm+t[now].rm), t[now].lm=Max(t[now].lm,t[now].sm+t[rs].lm), t[now].rm=Max(t[rs].rm,t[rs].sm+t[now].rm),t[now].sm+=t[rs].sm; } */ } int merge(int u,int v) { if(!u || !v) return u|v; if(t[u].key<t[v].key) { t[u].ch[1]=merge(t[u].ch[1],v),update(u); return u; } else { t[v].ch[0]=merge(u,t[v].ch[0]),update(v); return v; } } void split(int now,int k,int& x,int& y) { if(!now) return (void)(x=y=0); if(t[t[now].ch[0]].sz>=k) split(t[y=now].ch[0],k,x,t[now].ch[0]); else split(t[x=now].ch[1],k-t[t[now].ch[0]].sz-1,t[now].ch[1],y); update(now); } inline void ins(int p,int x) { int a,b; split(root,p-1,a,b),root=merge(merge(a,newnode(x)),b); } inline void del(int p) { int a,b,c; split(root,p-1,a,b),split(b,1,b,c),root=merge(a,c); } inline void rep(int p,int x) { int a,b,c; split(root,p-1,a,b),split(b,1,b,c),b=newnode(x),root=merge(a,merge(b,c)); } inline int qry(int x,int y) { int a,b,c,s; return split(root,y,b,c),split(b,x-1,a,b),s=t[b].mm,root=merge(a,merge(b,c)),s; } } using namespace FHQTreap; signed main(){ n=read(); int opt,p,x; while(n--) x=read(),root=merge(root,newnode(x)); m=read(); while(m--){ opt=cread(); switch(opt){ case 'I': p=read(),x=read(),ins(p,x); break; case 'D': p=read(),del(p); break; case 'R': p=read(),x=read(),rep(p,x); break; case 'Q': p=read(),x=read(),print(qry(p,x)); break; } } return Ot(),0; } ``` GSS 剩余一题...