• 【BZOJ2212】[POI2011]Tree Rotations (线段树合并)


    题解:

    傻逼题

    启发式合并线段树里面查$nlog^2$

    线段树合并顺便维护一下$nlogn$

    注意是叶子为n 总结点2n

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define rint register int
    #define IL inline
    #define rep(i,h,t) for(int i=h;i<=t;i++)
    #define dep(i,t,h) for(int i=t;i>=h;i--)
    #define ll long long
    #define me(x) memset(x,0,sizeof(x))
    #define mep(x,y) memcpy(x,y,sizeof(y))
    #define mid (t<=0?(h+t-1)/2:(h+t)/2)
    namespace IO{
        char ss[1<<24],*A=ss,*B=ss;
        IL char gc()
        {
            return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
        }
        template<class T> void read(T &x)
        {
            rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
            while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f; 
        }
        char sr[1<<24],z[20]; int Z,C1=-1;
        template<class T>void wer(T x)
        {
            if (x<0) sr[++C1]='-',x=-x;
            while (z[++Z]=x%10+48,x/=10);
            while (sr[++C1]=z[Z],--Z);
        }
        IL void wer1()
        {
            sr[++C1]=' ';
        }
        IL void wer2()
        {
            sr[++C1]='
    ';
        }
        template<class T>IL void maxa(T &x,T y) {if (x<y) x=y;}
        template<class T>IL void mina(T &x,T y) {if (x>y) x=y;} 
        template<class T>IL T MAX(T x,T y){return x>y?x:y;}
        template<class T>IL T MIN(T x,T y){return x<y?x:y;}
    };
    using namespace IO;
    const int N1=4.1e5;
    const int N2=7e6;
    int ch[N1][2],node,v[N1],rt[N1],n;
    ll ans,cnt1,cnt2;
    int gettree()
    {
        int x,u=++node;read(x);
        if(!x)ch[u][0]=gettree(),ch[u][1]=gettree();
        else v[u]=x;
        return u;
    }
    struct sgt{
        int sum[N2],ls[N2],rs[N2],cnt;
        void insert(int &x,int h,int t,int pos)
        {
            x=++cnt; sum[x]=1;
            if (h==t) return;
            if (pos<=mid) insert(ls[x],h,mid,pos);
            else insert(rs[x],mid+1,t,pos);
        }
        int merge(int x,int y)
        {
            if (!x||!y) return x^y;
            sum[x]+=sum[y]; 
            cnt1+=1ll*sum[ls[x]]*sum[rs[y]];
            cnt2+=1ll*sum[rs[x]]*sum[ls[y]];
            ls[x]=merge(ls[x],ls[y]);
            rs[x]=merge(rs[x],rs[y]);
            return x;
        }
    }S;
    void dfs(int x)
    {
        if (v[x])
        {
            S.insert(rt[x],1,n,v[x]); return;
        } 
        dfs(ch[x][0]);
        dfs(ch[x][1]);
        cnt1=0,cnt2=0;
        rt[x]=S.merge(rt[ch[x][0]],rt[ch[x][1]]);
        ans+=MIN(cnt1,cnt2);
    }
    int main()
    {
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
        read(n); gettree();
        dfs(1);
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    JAVA 执行系统命令
    Linux环境安装Elasticsearch
    JAVA 上传文件到本地服务器
    模仿新浪导航栏
    导航栏简单实现
    css实现简单导航栏
    css字体讲解内容
    模拟新闻页面模块
    [Win32]一个调试器的实现(六)显示源代码
    [Win32]一个调试器的实现(九)符号模型
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/10063854.html
Copyright © 2020-2023  润新知