【JZOJ 4986】 神祕物質
阿新 • • 發佈:2019-02-16
Description
Analysis
某神奇帝都OI冬令營的題
max x y相當於整個區間的最大減最小
min x y相當於相鄰兩個數差值最小值
insert,merge什麼的splay維護
比賽的時候沒時間拍了結果過掉了。。。
聽說塊鏈也可以過。。。也是裸的
為什麼OI比賽中要出板題==
Code
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int N=200005,INF=2147483640/2;
int n,tot,root,f[N],size[N],key[N],a[N][2],mx[N],mn[N],le[N],ri[N],cmn[N];
int pd(int x)
{
return x==a[f[x]][1];
}
int update(int x)
{
int ls=a[x][0],rs=a[x][1];
size[x]=1+size[ls]+size[rs];
mx[x]=mn[x]=key[x];
if(ls) mx[x]=max(mx[x],mx[ls]),mn[x]=min (mn[x],mn[ls]);
if(rs) mx[x]=max(mx[x],mx[rs]),mn[x]=min(mn[x],mn[rs]);
le[x]=le[ls],ri[x]=ri[rs];
if(!ls) le[x]=key[x];
if(!rs) ri[x]=key[x];
cmn[x]=INF;
if(ls) cmn[x]=min(abs(ri[ls]-key[x]),cmn[ls]);
if(rs) cmn[x]=min(cmn[x],min(abs(key[x]-le[rs]),cmn[rs]));
}
void rotate (int x)
{
int y=f[x],z=pd(x);
a[y][z]=a[x][1-z];
if(a[x][1-z]) f[a[x][1-z]]=y;
f[x]=f[y];
if(f[y]) a[f[y]][pd(y)]=x;
a[x][1-z]=y,f[y]=x;
update(y);
}
void splay(int x,int y)
{
if(!y) root=x;
while(f[x]!=y)
{
if(f[f[x]]!=y)
if(pd(x)==pd(f[x])) rotate(f[x]);
else rotate(x);
rotate(x);
}
update(x);
}
int kth(int x,int k)
{
if(size[a[x][0]]+1==k) return x;
if(k<=size[a[x][0]]) return kth(a[x][0],k);
else return kth(a[x][1],k-size[a[x][0]]-1);
}
void insert(int p,int z)
{
int x=kth(root,p+1),y=kth(root,p+2);
splay(x,0);splay(y,x);
a[y][0]=++tot,f[tot]=y,key[tot]=z,cmn[tot]=INF;
update(tot);update(y);update(x);
}
void del(int p)
{
int x=kth(root,p),y=kth(root,p+2);
splay(x,0),splay(y,x);
a[y][0]=0;
update(y);update(x);
}
void merge(int p,int z)
{
del(p);del(p);
insert(p-1,z);
}
int qmin(int l,int r)
{
int x=kth(root,l),y=kth(root,r+2);
splay(x,0),splay(y,x);
return cmn[a[y][0]];
}
int qmax(int l,int r)
{
int x=kth(root,l),y=kth(root,r+2);
splay(x,0),splay(y,x);
return mx[a[y][0]]-mn[a[y][0]];
}
int main()
{
char ch;
int x,y,_;
scanf("%d %d",&n,&_);
key[1]=cmn[1]=INF;
fo(i,2,n+1)
{
scanf("%d",&key[i]);cmn[i]=INF;
f[i]=i-1,a[i-1][1]=i;
update(i);
}
f[n+2]=n+1,a[n+1][1]=n+2,key[n+2]=cmn[n+2]=INF;
splay(n+2,0);
tot=n+2;
scanf("\n");
while(_--)
{
scanf("%c",&ch);
if(ch=='m')
{
scanf("%c",&ch);
if(ch=='e')
{
scanf("rge %d %d\n",&x,&y);
merge(x,y);
}
if(ch=='i')
{
scanf("n %d %d\n",&x,&y);
printf("%d\n",qmin(x,y));
}
if(ch=='a')
{
scanf("x %d %d\n",&x,&y);
printf("%d\n",qmax(x,y));
}
}
else
{
scanf("nsert %d %d\n",&x,&y);
insert(x,y);
}
}
return 0;
}