1. 程式人生 > >BZOJ4864 BeiJing 2017 Wc神祕物質(splay)

BZOJ4864 BeiJing 2017 Wc神祕物質(splay)

  splay維護區間最大值、最小值、相鄰兩數差的絕對值的最小值即可。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 100010
#define inf 2100000000
#define lson tree[k].ch[0]
#define rson tree[k].ch[1]
char
getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while
(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n,m,a[N],cnt,root; struct data{int ch[2],fa,x,d,s,max,min,mind; }tree[N<<1]; void up(int k) { tree[k].max=max(max(tree[lson].max,tree[rson].max),tree[k].x); tree[k].min=min(min(tree[lson].min,tree[rson].min),tree[k].x); tree[k].mind
=min(min(tree[lson].mind,tree[rson].mind),tree[k].d); tree[k].s=tree[lson].s+tree[rson].s+1; } int build(int l,int r,int from) { if (l>r) return 0; int mid=l+r>>1,k=++cnt;tree[k].fa=from;tree[k].s=1; tree[k].x=tree[k].max=tree[k].min=a[mid]; tree[k].d=tree[k].mind=abs(a[mid]-a[mid+1]); lson=build(l,mid-1,k),rson=build(mid+1,r,k); up(k); return k; } int whichson(int k){return tree[tree[k].fa].ch[1]==k;} void move(int k) { int fa=tree[k].fa,gf=tree[fa].fa,p=whichson(k); tree[gf].ch[whichson(fa)]=k,tree[k].fa=gf; tree[tree[k].ch[!p]].fa=fa,tree[fa].ch[p]=tree[k].ch[!p]; tree[k].ch[!p]=fa,tree[fa].fa=k; up(fa),up(k); } void splay(int k,int rt) { while (tree[k].fa!=rt) { int fa=tree[k].fa; if (tree[fa].fa!=rt) if (whichson(k)^whichson(fa)) move(k); else move(fa); move(k); } if (!rt) root=k; } int find(int k,int x) { if (tree[lson].s==x) return k; else if (tree[lson].s>x) return find(lson,x); else return find(rson,x-tree[lson].s-1); } void ins(int k,int x) { int p=find(root,k-1),q=find(root,k); splay(p,0),splay(q,p); k=++cnt;tree[k].fa=q;tree[k].s=1; tree[k].x=tree[k].max=tree[k].min=x; tree[k].d=tree[k].mind=abs(x-tree[q].x); tree[q].ch[0]=k,up(q); tree[p].d=abs(tree[p].x-x),up(p); } void del(int k) { int p=find(root,k-1),q=find(root,k+1); splay(p,0),splay(q,p); tree[q].ch[0]=0,up(q); tree[p].d=abs(tree[p].x-tree[q].x),up(p); } int query(int l,int r,int op) { int p=find(root,l-1),q=find(root,r+1); splay(p,0),splay(q,p); int k=tree[q].ch[0]; if (op==0) return tree[k].max; else if (op==1) return tree[k].min; else return tree[k].mind; } int main() { #ifndef ONLINE_JUDGE freopen("bzoj4864.in","r",stdin); freopen("bzoj4864.out","w",stdout); const char LL[]="%I64d\n"; #else const char LL[]="%lld\n"; #endif n=read(),m=read(); for (int i=1;i<=n;i++) a[i]=read(); tree[0].max=tree[0].d=-inf,tree[0].min=tree[0].mind=tree[0].d=inf; root=build(0,n+1,0); while (m--) { char c=getc(); if (c=='m') { c=getc(); if (c=='e') { int x=read(),y=read(); del(x);del(x);ins(x,y); } else { int l=read(),r=read(); if (c=='a') printf("%d\n",query(l,r,0)-query(l,r,1)); else printf("%d\n",query(l,r-1,2)); } } else { int x=read(),y=read(); ins(x+1,y); } } return 0; }