1. 程式人生 > >【JZOJ 4986】 神祕物質

【JZOJ 4986】 神祕物質

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; }