您的位置:首页 > 其它

BZOJ1500: [NOI2005]维修数列

2017-02-15 08:14 501 查看
传送门

写完这道题后我有一句妈卖批不知道当不当讲?

具体的怎么操作大家都很容易脑补出来,简单说几点需要注意的:

1.赋初值的时候注意把t[0].mx设为-oo,以及0节点和N+1节点。

2.每次对对应的区间操作完后注意进行两次reload

3.每个节点的lx与rx可以为0,所以mx不可以对lx与rx取max。

4.对于区间翻转后不能立刻在当前区间进行reload,注意交换lx与rx。

5.fix如果为负值的话mx应该为val而不是sum

6.注意回收内存

//BZOJ1500
//by Cydiater
//2017.2.14
#include <iostream>
#include <queue>
#include <map>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <bitset>
#include <set>
#include <vector>
#include <complex>
using namespace std;
#define ll long long
#define up(i,j,n)	for(int i=j;i<=n;i++)
#define down(i,j,n)	for(int i=j;i>=n;i--)
#define cmax(a,b)	a=max(a,b)
#define cmin(a,b)	a=min(a,b)
#define FILE		"seq2005"
const int MAXN=5e5+5;
const int oo=0x3f3f3f3f;
inline int read(){
char ch=getchar();int x=0,f=1;
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int N,M,arr[MAXN];
int top=0,cnt=0,root=0;
struct SplayTree{
int son[2],lx,rx,mx,siz,val,sum,fa,tag,fix;
}t[MAXN];
char s[MAXN];
queue<int>Q;
namespace solution{
inline int get(int k){return t[t[k].fa].son[1]==k;}
inline void reload(int k){
int s1=t[k].son[0],s2=t[k].son[1];
t[k].sum=t[s1].sum+t[s2].sum+t[k].val;
t[k].siz=t[s1].siz+t[s2].siz+1;
t[k].mx=max(t[s1].mx,t[s2].mx);
cmax(t[k].mx,t[s1].rx+t[k].val+t[s2].lx);
t[k].lx=max(t[s1].lx,t[s1].sum+t[k].val+t[s2].lx);
t[k].rx=max(t[s2].rx,t[s2].sum+t[k].val+t[s1].rx);
}
inline void rotate(int k){
int old=t[k].fa,oldf=t[old].fa,which=get(k);
t[old].son[which]=t[k].son[which^1];t[t[old].son[which]].fa=old;
t[old].fa=k;t[k].son[which^1]=old;
t[k].fa=oldf;
if(oldf)t[oldf].son[t[oldf].son[1]==old]=k;
reload(old);reload(k);
}
void Pushdown(int k){
int s1=t[k].son[0],s2=t[k].son[1];
if(t[k].fix!=1001){
int fix=t[k].fix;
t[k].fix=1001;
if(s1){
t[s1].val=t[s1].fix=fix;
t[s1].sum=t[s1].siz*fix;
if(fix>=0)t[s1].lx=t[s1].rx=t[s1].mx=t[s1].sum;
else{
t[s1].lx=t[s1].rx=0;
t[s1].mx=fix;
}
}
if(s2){
t[s2].val=t[s2].fix=fix;
t[s2].sum=t[s2].siz*fix;
if(fix>=0)t[s2].lx=t[s2].rx=t[s2].mx=t[s2].sum;
else{
t[s2].lx=t[s2].rx=0;
t[s2].mx=fix;
}
}
}
if(t[k].tag){
if(s1)t[s1].tag^=1;if(s2)t[s2].tag^=1;
swap(t[s1].son[0],t[s1].son[1]);
swap(t[s1].lx,t[s1].rx);
swap(t[s2].son[0],t[s2].son[1]);
swap(t[s2].lx,t[s2].rx);
t[k].tag=0;
}
}
inline void splay(int k,int aim){
for(int fa;(fa=t[k].fa);rotate(k)){
if(k==aim)break;
else if(fa==aim){
rotate(k);
break;
}else if(t[fa].fa==aim){
rotate(get(fa)==get(k)?fa:k);
rotate(k);
break;
}else rotate(get(fa)==get(k)?fa:k);
}
if(aim==root)root=k;
}
void Build(int L,int R,int &k,int fa){
if(!k){
k=Q.front();
Q.pop();
}
int mid=(L+R)>>1;
t[k].fa=fa;t[k].val=arr[mid];t[k].siz=1;t[k].fix=1001;
if(L==R){
t[k].son[0]=t[k].son[1]=0;
t[k].lx=t[k].rx=t[k].sum=t[k].mx=t[k].val;
cmax(t[k].lx,0);
cmax(t[k].rx,0);
return;
}
if(L<=mid-1)Build(L,mid-1,t[k].son[0],k);
if(mid+1<=R)Build(mid+1,R,t[k].son[1],k);
reload(k);
}
int rnk(int rank){
int now=root;
while(rank){
Pushdown(now);
int lsiz=t[now].son[0]?t[t[now].son[0]].siz:0;
if(rank>lsiz){
if(rank==lsiz+1)return now;
rank-=lsiz+1;
now=t[now].son[1];
}else now=t[now].son[0];
}
return now;
}
void Match(int L,int R){
int kl=rnk(L),kr=rnk(R+2);
splay(kl,root);splay(kr,t[root].son[1]);
}
void Rec(int now){
Q.push(now);
if(t[now].son[0])Rec(t[now].son[0]);
if(t[now].son[1])Rec(t[now].son[1]);
t[now].son[0]=t[now].son[1]=t[now].lx=t[now].mx=t[now].rx=t[now].sum=t[now].siz=t[now].val=t[now].tag=0;
t[now].fix=1001;
}
void Insert(int pos,int tol){
Match(pos+1,pos);
up(i,1,tol)arr[i]=read();
int rt=0,tmp=t[root].son[1];
Build(1,tol,rt,t[tmp].son[0]);
t[tmp].son[0]=rt;
t[rt].fa=tmp;
reload(tmp);
reload(t[tmp].fa);
}
void Del(int pos,int tol){
int L=pos,R=pos+tol-1;
Match(L,R);
int tmp=t[root].son[1];
Rec(t[tmp].son[0]);
t[tmp].son[0]=0;
reload(tmp);
reload(t[tmp].fa);
}
void Fix(int pos,int tol){
int L=pos,R=pos+tol-1;
Match(L,R);
int tmp=t[t[root].son[1]].son[0];
t[tmp].fix=t[tmp].val=read();
t[tmp].sum=t[tmp].siz*t[tmp].val;
t[tmp].lx=max(0,t[tmp].siz*t[tmp].val);
t[tmp].rx=t[tmp].lx;
t[tmp].mx=max(t[tmp].val,t[tmp].sum);
reload(t[tmp].fa);
reload(root);
}
void Rev(int pos,int tol){
int L=pos,R=pos+tol-1;
Match(L,R);
int tmp=t[t[root].son[1]].son[0];
if(t[tmp].fix==1001){
t[tmp].tag^=1;
swap(t[tmp].son[0],t[tmp].son[1]);
swap(t[tmp].lx,t[tmp].rx);
reload(t[tmp].fa);
reload(root);
}
}
int Sum(int pos,int tol){
int L=pos,R=pos+tol-1;
Match(L,R);
return t[t[t[root].son[1]].son[0]].sum;
}
void Prepare(){
N=read();M=read();
up(i,1,500000)Q.push(i);
up(i,1,N)arr[i]=read();
arr[0]=arr[N+1]=t[0].mx=-oo;
Build(0,N+1,root,0);
}
void Solve(){
while(M--){
scanf("%s",s);
int pos,tol;
if(s[0]!='M'||s[2]!='X'){pos=read();tol=read();}
if(s[0]=='I')Insert(pos,tol);
else if(s[0]=='D')Del(pos,tol);
else if(s[0]=='M'&&s[2]=='K')Fix(pos,tol);
else if(s[0]=='R')Rev(pos,tol);
else if(s[0]=='G')	printf("%d\n",Sum(pos,tol));
else			printf("%d\n",t[root].mx);
}
}
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
using namespace solution;
Prepare();
Solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: