• 51 nod 1297 管理二叉树


    原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1297

    先是暴力加优化T了最后两个点……

    我还是来想想正解吧。

    先写棵线段树把二叉搜索树建出来,然后在树上做下点分治就好了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define lp (p<<1)
    #define rp ((p<<1)|1)
    using namespace std;
    
    int read_p,read_ca;
    inline int read(){
        read_p=0;read_ca=getchar();
        while(read_ca<'0'||read_ca>'9') read_ca=getchar();
        while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar();
        return read_p;
    }
    struct na{int y,z,ne,k;}b[200001],B[4000001];
    int n,m,a[200001],x,y,l[200001],num=0,de[200001],L[200001],Num=0,s[200001],Si,ro,ma;
    bool bo[200001];
    long long mmh[200001][5],S[200001][5];
    long long MMH=0;
    inline void in(int x,int y){b[++num].y=y;b[num].ne=l[x];l[x]=num;}
    inline void In(int x,int y,int z,int k){B[++Num].y=y;B[Num].z=z;B[Num].k=k;B[Num].ne=L[x];L[x]=Num;}
    struct tree{int ma,mi;}t[4000001];
    void add(int p,int l,int r,int v){
        if (a[t[p].ma]<a[v]||t[p].ma==0) t[p].ma=v;
        if (a[t[p].mi]>a[v]||t[p].mi==0) t[p].mi=v;
        if (l==r) return;
        int mid=l+r>>1;
        if (a[v]<=mid) add(lp,l,mid,v);else add(rp,mid+1,r,v);
    }
    int quea(int p,int l,int r,int R){
        if (R>=r) return t[p].ma;
        int mid=l+r>>1;
        if (R<=mid) return quea(lp,l,mid,R);else if (mid=quea(rp,mid+1,r,R)) return mid;else return t[lp].ma;
    }
    int quei(int p,int l,int r,int R){
        if (R<=l) return t[p].mi;
        int mid=l+r>>1;
        if (R>mid) return quei(rp,mid+1,r,R);else if (mid=quei(lp,l,mid,R)) return mid;else return t[rp].mi;
    }
    void gs(int x,int f){
        s[x]=1;
        int u=0;
        for (register int i=l[x];i;i=b[i].ne)
        if (b[i].y!=f&&!bo[b[i].y]){
            gs(b[i].y,x);
            s[x]+=s[b[i].y];
            if (u<s[b[i].y]) u=s[b[i].y];
        }
        if (Si-s[x]>u) u=Si-s[x];
        if (u<ma) ma=u,ro=x;
    }
    void dfs(int x,int f,int r,int z,int k){
        s[x]=1;
        In(x,r,z,k);
        for (register int i=l[x];i;i=b[i].ne)
        if (!bo[b[i].y]&&b[i].y!=f) dfs(b[i].y,x,r,z+1,k),s[x]+=s[b[i].y];
    }
    void work(int x,int S){
        Si=S;ma=1e9;gs(x,0);bo[x=ro]=1;
        int u=0;
        for (register int i=l[x];i;i=b[i].ne) if (!bo[b[i].y]) dfs(b[i].y,x,x,1,++u);In(x,x,0,++u);
        for (register int i=l[x];i;i=b[i].ne) if (!bo[b[i].y]) work(b[i].y,s[b[i].y]);
    }
    int main(){
        register int i,j;
        n=read();a[n+1]=n+1;add(1,0,n+1,0);add(1,0,n+1,n+1);
        a[1]=read();add(1,0,n+1,1);de[1]=1;
        for (i=2;i<=n;i++){
            a[i]=read();
            x=quea(1,0,n+1,a[i]-1);y=quei(1,0,n+1,a[i]+1);
            if (de[x]>de[y]){
                in(x,i);
                in(i,x);
                de[i]=de[x]+1;
            }else{
                in(y,i);
                in(i,y);
                de[i]=de[y]+1;
            }
            add(1,0,n+1,i);
        }
        work(1,n);
        for (i=1;i<=n;i++){
            for (j=L[i];j;j=B[j].ne) MMH+=1LL*B[j].z*(S[B[j].y][0]-S[B[j].y][B[j].k])+mmh[B[j].y][0]-mmh[B[j].y][B[j].k],
            mmh[B[j].y][0]+=B[j].z,mmh[B[j].y][B[j].k]+=B[j].z,S[B[j].y][0]++,S[B[j].y][B[j].k]++;
            printf("%lld
    ",MMH);
        }
    }
    View Code
  • 相关阅读:
    基于jquery的web在线流程图设计器gooFlow
    angularJS学习笔记二
    angularJS学习笔记一
    JavaScript作用域链详解
    图片查看器(可拖拽,缩放,轮播)
    小议window.event || ev
    Vue安装准备工作
    让VS2013添加新类时自动添加public关键字
    win10太垃圾,真的不好用。
    Bind 和 ScaffoldColumn[转]
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5764382.html
Copyright © 2020-2023  润新知