[BZOJ4864][BeiJing2017Wc]神秘物质(splay)

首先merge就是先delete两次再insert,Max就是整个区间的最大值减最小值,Min就是区间中所有相邻两数差的最小值。

Splay支持区间最大值,区间最小值,区间相邻差最小值即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 5 using namespace std;
 6 
 7 const int N=200010,inf=1e9;
 8 char op[10];
 9 int n,m,nd,rt,x,y,v[N],d[N],sz[N],mx[N],mn[N],mnd[N],a[N],ch[N][2],f[N];
10 
11 int Abs(int x){ return x<0 ? -x : x; }
12 
13 void upd(int x){
14     int ls=ch[x][0],rs=ch[x][1];
15     sz[x]=sz[ls]+sz[rs]+1;
16     mn[x]=min(v[x],min(mn[ls],mn[rs]));
17     mx[x]=max(v[x],max(mx[ls],mx[rs]));
18     mnd[x]=min(d[x],min(mnd[ls],mnd[rs]));
19 }
20 
21 void rot(int &rt,int x){
22     int y=f[x],z=f[y],w=ch[y][1]==x;
23     if (y==rt) rt=x; else ch[z][ch[z][1]==y]=x;
24     f[y]=x; f[x]=z; f[ch[x][w^1]]=y;
25     ch[y][w]=ch[x][w^1]; ch[x][w^1]=y; upd(y);
26 }
27 
28 void splay(int &rt,int x){
29     while (x!=rt){
30         int y=f[x],z=f[y];
31         if (y!=rt) (ch[z][1]==y ^ ch[y][1]==x) ? rot(rt,x) : rot(rt,y);
32         rot(rt,x);
33     }
34     upd(x);
35 }
36 
37 int build(int l,int r){
38     if (l>r) return 0;
39     int x=++nd,mid=(l+r)>>1;
40     v[x]=a[mid]; d[x]=Abs(a[mid]-a[mid-1]); sz[x]=1;
41     f[ch[x][0]=build(l,mid-1)]=x; f[ch[x][1]=build(mid+1,r)]=x;
42     upd(x); return x;
43 }
44 
45 int find(int x,int k){
46     if (sz[ch[x][0]]+1==k) return x;
47     if (k<=sz[ch[x][0]]) return find(ch[x][0],k);
48         else return find(ch[x][1],k-sz[ch[x][0]]-1);
49 }
50 
51 void ins(int p,int k){
52     int x=find(rt,p+1),y=find(rt,p+2);
53     splay(rt,x); splay(ch[x][1],y);
54     v[++nd]=k; d[nd]=Abs(v[nd]-v[x]); f[nd]=y; sz[nd]=1;
55     ch[y][0]=nd; d[y]=Abs(v[y]-v[nd]); upd(nd); upd(y); upd(x);
56 }
57 
58 void del(int p){
59     int x=find(rt,p),y=find(rt,p+2);
60     splay(rt,x); splay(ch[x][1],y);
61     ch[y][0]=0; d[y]=Abs(v[y]-v[x]); upd(y); upd(x);
62 }
63 
64 int que(int l,int r,int op){
65     int x=find(rt,l),y=find(rt,r+2);
66     splay(rt,x); splay(ch[x][1],y);
67     return op==0 ? mx[ch[y][0]] : (op==1 ? mn[ch[y][0]] : mnd[ch[y][0]]);
68 }
69 
70 int main(){
71     freopen("bzoj4864.in","r",stdin);
72     freopen("bzoj4864.out","w",stdout);
73     scanf("%d%d",&n,&m); mnd[0]=mn[0]=inf;
74     rep(i,1,n) scanf("%d",&a[i]);
75     rt=build(0,n+1);
76     rep(i,1,m){
77         scanf("%s%d%d",op,&x,&y);
78         if (op[1]=='e') del(x),del(x),ins(x-1,y);
79         if (op[1]=='n') ins(x,y);
80         if (op[1]=='a') printf("%d
",que(x,y,0)-que(x,y,1));
81         if (op[1]=='i') printf("%d
",que(x+1,y,2));
82     }
83     return 0;
84 }
原文地址:https://www.cnblogs.com/HocRiser/p/10127580.html