HYSBZ 1500 维修数列
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1500
操作1:把要插入的数字先建成一颗树,然后splay相应位置,直接将树连上去
操作2,3,4,5:都是splay普通操作
操作6:像维护线段树一样,同时维护max,maxl,maxr就行了
注意点:
旋转时maxl和maxr也要交换
要使用内存池,当弹出一个节点时,将它的两个子树丢进内存池中
same的值可能为0,所以要设为inf
max不能为空,所以初始应设成-inf,而不是0,否则update时会出错
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define lson i<<1
#define rson i<<1|1
using namespace std;
const int N=5e5+5;
const int inf=1e9;
int head,tail,q[N*10],root;
int a[N],b[N],f[N],ch[N][2],key[N],sz[N],same[N],rev[N],sum[N],maxl[N],maxr[N],maxx[N];
inline void Clear(int x)
{
f[x]=ch[x][0]=ch[x][1]=key[x]=sz[x]=rev[x]=sum[x]=maxl[x]=maxr[x]=0;
same[x]=inf;
maxx[x]=-inf;
}
inline int get(int x)
{
return ch[f[x]][1]==x;
}
inline void delp(int x)
{
q[++tail]=x;
}
int newp()
{
head++;
if (ch[q[head]][0]) delp(ch[q[head]][0]);
if (ch[q[head]][1]) delp(ch[q[head]][1]);
Clear(q[head]);
return q[head];
}
void update(int x)
{
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+key[x];
maxl[x]=max(maxl[ch[x][0]],key[x]+sum[ch[x][0]]+maxl[ch[x][1]]);
maxr[x]=max(maxr[ch[x][1]],key[x]+sum[ch[x][1]]+maxr[ch[x][0]]);
maxx[x]=max(maxx[ch[x][0]],maxx[ch[x][1]]);
maxx[x]=max(maxx[x],maxr[ch[x][0]]+key[x]+maxl[ch[x][1]]);
}
void pushdown(int x)
{
if (x==0) return;
if (same[x]!=inf)
{
if (ch[x][0])
{
int lch=ch[x][0];
key[lch]=same[x];
sum[lch]=sz[lch]*same[x];
if (same[x]>=0)
maxx[lch]=maxl[lch]=maxr[lch]=sum[lch];
else
{
maxx[lch]=same[x];
maxl[lch]=maxr[lch]=0;
}
same[lch]=same[x];
}
if (ch[x][1])
{
int rch=ch[x][1];
key[rch]=same[x];
sum[rch]=sz[rch]*same[x];
if (same[x]>=0)
maxx[rch]=maxl[rch]=maxr[rch]=sum[rch];
else
{
maxx[rch]=same[x];
maxl[rch]=maxr[rch]=0;
}
same[rch]=same[x];
}
same[x]=inf;
}
if (rev[x])
{
if (ch[x][0])
{
int now=ch[x][0];
rev[now]^=1;
swap(ch[now][0],ch[now][1]);
swap(maxl[now],maxr[now]);
}
if (ch[x][1])
{
int now=ch[x][1];
rev[now]^=1;
swap(ch[now][0],ch[now][1]);
swap(maxl[now],maxr[now]);
}
rev[x]=0;
}
}
int build(int l,int r,int fa,int *val)
{
if (l>r) return 0;
int mid=(l+r)>>1;
int now=newp();
f[now]=fa;key[now]=val[mid];maxx[now]=val[mid];
int lch=build(l,mid-1,now,val);
int rch=build(mid+1,r,now,val);
ch[now][0]=lch;ch[now][1]=rch;
update(now);
return now;
}
void Rotate(int x)
{
pushdown(f[x]);
pushdown(x);
int fa=f[x],ff=f[fa],kind=get(x);
ch[fa][kind]=ch[x][kind^1];f[ch[x][kind^1]]=fa;
ch[x][kind^1]=fa;f[fa]=x;
f[x]=ff;
if (ff)
ch[ff][ch[ff][1]==fa]=x;
update(fa);
update(x);
}
void splay(int x,int y)
{
for(int fa;(fa=f[x])!=y;Rotate(x))
if (f[fa]!=y)
Rotate((get(fa)==get(x))?fa:x);
if (y==0) root=x;
}
int Find(int x)
{
int now=root;
while(1)
{
pushdown(now);
if (ch[now][0]&&sz[ch[now][0]]>=x)
now=ch[now][0];
else
{
x-=sz[ch[now][0]];
if (x==1) return now;
x--;
now=ch[now][1];
}
}
}
void Treaval(int x) {
if(x) {
pushdown(x);
Treaval(ch[x][0]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,key = %2d sum = %2d maxsum=%2d \n",x,ch[x][0],ch[x][1],f[x],sz[x],key[x],sum[x],maxx[x]);
Treaval(ch[x][1]);
}
}
void debug() {printf("%d\n",root);Treaval(root);}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
a[1]=-inf;a[n+2]=inf;maxx[0]=-inf;
for(int i=1;i<=n;i++)
scanf("%d",&a[i+1]);
for(int i=1;i<=500000;i++)
delp(i);
root=build(1,n+2,0,a);
char s[20];
int pos,tot,c;
while(m--)
{
scanf("%s",s);
switch(s[0])
{
case 'I':
{
scanf("%d%d",&pos,&tot);
for(int i=1;i<=tot;i++)
scanf("%d",&b[i]);
int now=build(1,tot,0,b);
int aa=Find(pos+1);
int bb=Find(pos+2);
splay(aa,0);
splay(bb,aa);
ch[ch[root][1]][0]=now;
f[now]=ch[root][1];
update(ch[root][1]);
update(root);
//debug();
break;
}
case 'D':
{
scanf("%d%d",&pos,&tot);
int aa=Find(pos);
int bb=Find(pos+tot+1);
splay(aa,0);
splay(bb,aa);
delp(ch[ch[root][1]][0]);
ch[ch[root][1]][0]=0;
update(ch[root][1]);
update(root);
//debug();
break;
}
case 'M':
if (s[2]=='K')
{
scanf("%d%d%d",&pos,&tot,&c);
int aa=Find(pos);
int bb=Find(pos+tot+1);
splay(aa,0);
splay(bb,aa);
int now=ch[ch[root][1]][0];
same[now]=c;
key[now]=c;
sum[now]=c*sz[now];
if (c>=0)
maxx[now]=maxl[now]=maxr[now]=sum[now];
else
{
maxx[now]=c;
maxl[now]=maxr[now]=0;
}
update(ch[root][1]);
update(root);
//debug();
}
else
{
int aa=Find(1);
int bb=Find(sz[root]);
splay(aa,0);
splay(bb,aa);
printf("%d\n",maxx[ch[ch[root][1]][0]]);
}
break;
case 'R':
{
scanf("%d%d",&pos,&tot);
if (tot==1) break;
int aa=Find(pos);
int bb=Find(pos+tot+1);
splay(aa,0);
splay(bb,aa);
int now=ch[ch[root][1]][0];
rev[now]^=1;
swap(ch[now][0],ch[now][1]);
swap(maxl[now],maxr[now]);
break;
}
case 'G':
{
scanf("%d%d",&pos,&tot);
int aa=Find(pos);
int bb=Find(pos+tot+1);
splay(aa,0);
splay(bb,aa);
//debug();
printf("%d\n",sum[ch[ch[root][1]][0]]);
break;
}
}
}
return 0;
}

浙公网安备 33010602011771号