[BJWC2017]神秘物质 Treap

来源:互联网 发布:软件开发培训学校 编辑:程序博客网 时间:2024/04/27 21:29

非旋转Treap
合并相当于删除两个点增加一个点
查询直接把子树切出来再拼回去

#include <bits/stdc++.h>#pragma GCC optimize(2)#define L tr[t].l#define R tr[t].r#define N 200050#define INF 2147483647using namespace std;typedef pair<int,int> pii;#define MP make_pairvoid GP(int &x,int &y,pii p) { x = p.first, y = p.second; }struct Node{ int a,q,l,r,s1,s2,v1,v2,ans; }tr[N];int sz[N],re,cnt,x,y,e,r1,r2,rt,n,m;inline void ut(int &x,int y) {x = min(x,y);}inline int Abs(int x) { return x<0 ? -x : x; }inline int rd() { int r; scanf("%d",&r); return r; }void up(int t) {    assert(t);    sz[t] = sz[L]+sz[R]+1;    tr[t].s1 = min(tr[L].s1, tr[R].s1),    tr[t].s1 = min(tr[t].s1, tr[t].a);    tr[t].s2 = max(tr[L].s2, tr[R].s2);    tr[t].s2 = max(tr[t].s2, tr[t].a);    tr[t].ans = INF;     ut(tr[t].ans, tr[L].ans);    ut(tr[t].ans, tr[R].ans);    L ? ut(tr[t].ans, Abs(tr[t].a-tr[L].v2)) : (void)0;    R ? ut(tr[t].ans, Abs(tr[t].a-tr[R].v1)) : (void)0;    tr[t].v1 = L ? tr[L].v1 : tr[t].a,    tr[t].v2 = R ? tr[R].v2 : tr[t].a;}int mer(int x,int y) {    if (!x||!y) return x+y;    return         tr[x].q < tr[y].q ?        ( tr[x].r = mer(tr[x].r,y), up(x), x ):        ( tr[y].l = mer(x,tr[y].l), up(y), y );}#define cr (sz[L]+1)pii spl(int t,int k) {    if (!k) return MP(0,t);    if (k==sz[t]) return MP(t,0);    return         k < cr ?        ( GP(re, L, spl(L,k   )), up(t), MP(re,t) ):        ( GP(R, re, spl(R,k-cr)), up(t), MP(t,re) );}int merge(int a,int b,int c) { return mer( mer(a,b),c ); }void nN(int e) {     tr[++cnt] = (Node){e,rand(),0,0,e,e,e,e,INF}; sz[cnt] = 1; }void solve1() {    x = rd(), e = rd();    GP(r1,rt,spl(rt,x-1)), GP(rt,r2,spl(rt,2));    nN(e);    rt = merge(r1,cnt,r2);}void solve2() {    x = rd(), e = rd();    GP(r1,r2,spl(rt,x));    nN(e);    rt = merge(r1,cnt,r2);}void solve3(int cd) {    x = rd(), y = rd();    GP(rt,r2,spl(rt,y)),    GP(r1,rt,spl(rt,x-1));    printf("%d\n",cd == 1 ? tr[rt].s2-tr[rt].s1 : tr[rt].ans);    rt = merge(r1,rt,r2);}int main() {    n = rd(), m = rd();    tr[0].ans = INF, tr[0].s1 = INF, tr[0].s2 = -INF;    for (int _=1;_<=n;_++)         nN(rd()), rt = _==1? 1 : mer(rt,_);    while (m--) {        char cmd[10]; scanf("%s",cmd+1);        assert(1);        cmd[1]+cmd[2] == 'm'+'e' ? solve1() :(void)0;        cmd[1]+cmd[2] == 'i'+'n' ? solve2() :(void)0;        cmd[1]+cmd[2] == 'm'+'a' ? solve3(1) :(void)0;        cmd[1]+cmd[2] == 'm'+'i' ? solve3(2) :(void)0;    }    return 0;} 
0 0