您的位置:首页 > 其它

[JZOJ4986] 神秘物质(splay模板)

2017-03-03 20:37 387 查看

Description





Solution

发现极差最小值必定相邻,最大值就是区间最大减最小。

splay直接维护

Code

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define N 200005
#define INF 1e9
using namespace std;
int fn
,mx
,mi
,s1
,s
,dt
,ft
,son
[2],n,m,n1,rt,sz
;
int read()
{
int x=0;
char c;
scanf("%c",&c);
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
if(scanf("%c",&c)==EOF) break;
}
return x;
}
string rd()
{
char c;
string st="";
scanf("%c",&c);
while(c!=' ')
{
st+=c;
scanf("%c",&c);
}
return st;
}
void up(int k)
{
if(k==0)
{
sz[k]=0;
return;
}
int l=son[k][0],r=son[k][1];
mx[k]=mi[k]=dt[k],s[k]=abs(s1[k]),sz[k]=1+sz[l]+sz[r];
if(l>2)
{
if(mx[l]>mx[k]) mx[k]=mx[l];
if(mi[l]<mi[k]) mi[k]=mi[l];
if(s[l]<s[k]) s[k]=s[l];
}
if(r>2)
{
if(mx[r]>mx[k]) mx[k]=mx[r];
if(mi[r]<mi[k]) mi[k]=mi[r];
if(s[r]<s[k]) s[k]=s[r];
}
}
void link(int x,int y,int p)
{
if(y) ft[y]=x,fn[y]=p;
if(x) son[x][p]=y;
}
int find(int v)
{
int k=rt,v1=sz[k]-sz[son[k][1]];
while(v1!=v)
{
if(v>v1) v-=v1,k=son[k][1];
else k=son[k][0];
v1=sz[k]-sz[son[k][1]];
}
return k;
}
void rot(int k)
{
int f=ft[k],p=fn[k],s=son[k][1-p];
link(ft[f],k,fn[f]),link(f,s,p),link(k,f,1-p);
up(f),up(k),up(ft[k]);
}
void splay(int k,int f)
{
while(ft[k]!=f)
{
if(ft[ft[k]]==f) rot(k);
else if(fn[k]==fn[ft[k]]) rot(ft[k]),rot(k);
else rot(k),rot(k);
}
if(f==0) rt=k;
}
void nwp(int x,int y,int v)
{
splay(x,0),splay(y,rt);
dt[++n1]=v;
s1[n1]=v-dt[x],s1[y]=dt[y]-v;
link(n1,y,1),link(x,n1,1);
up(y),up(n1),up(x);
}
void del(int x,int y,int z,int v)
{
splay(x,0),splay(y,x),splay(z,y);
s1[x]+=-dt[x]+v,dt[x]=v,s1[z]=dt[z]-v;
link(x,z,1);
up(z),up(x);
}
int main()
{
cin>>n>>m;
n1=2,rt=1;
dt[1]=dt[2]=0;
s1[1]=s1[2]=INF;
link(1,2,1);
up(2),up(1);
fo(i,1,n)
{
int x,ls=find(i);
scanf("%d",&x);
nwp(ls,2,x);
}
fo(i,1,m)
{
scanf("\n");
string st=rd();
int x=read(),y=read(),p,q;
p=find(++x);
if(st=="insert") nwp(p,find(x+1),y);
if(st=="merge") del(p,find(x+1),find(x+2),y);
if(st=="max")
{
splay(find(x-1),0),splay(q=find((++y)+1),rt);
printf("%d\n",mx[son[q][0]]-mi[son[q][0]]);
}
if(st=="min")
{
splay(find(x),0),splay(q=find((++y)+1),rt);
printf("%d\n",s[son[q][0]]);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: