• 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
    ";
    #else
        const char LL[]="%lld
    ";
    #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
    ",query(l,r,0)-query(l,r,1));
                    else printf("%d
    ",query(l,r-1,2));
                }
            }
            else
            {
                int x=read(),y=read();
                ins(x+1,y);
            }
        }
        return 0;
    }
  • 相关阅读:
    [CareerCup] 8.1 Implement Blackjack 实现21点纸牌
    [LeetCode] H-Index 求H指数
    [CareerCup] 7.7 The Number with Only Prime Factors 只有质数因子的数字
    [CareerCup] 7.6 The Line Passes the Most Number of Points 经过最多点的直线
    Ionic实战一:Ionic仿照微信项目
    ionic3+angular4+cordova 项目实例
    Android 给EditText添加下划线
    浅谈移动优先的跨终端Web 解决方案
    Android环信即时通讯集成坑爹 注册报错208解决
    Android自定义控件 -- 带边框的TextView
  • 原文地址:https://www.cnblogs.com/Gloid/p/10010316.html
Copyright © 2020-2023  润新知