zoukankan      html  css  js  c++  java
  • bzoj2212

    题解:

    线段树合并

    比较一下哪一种方案的逆序对少

    代码:

    #include<bits/stdc++.h>  
    using namespace std; 
    const int N=4000005;
    typedef long long ll; 
    ll ans,ANS,a[N],cnt,ch[N][2],rt[N],cn,CH[N][2],sum[N],CNT,n;  
    void addnew(ll &x,ll l,ll r,ll v)  
    {  
        CNT++;x=CNT;  
        sum[x]++;  
        if (l==r) return;  
        ll mid=(l+r)/2;  
        if (v<=mid) addnew(ch[x][0],l,mid,v);  
        else addnew(ch[x][1],mid+1,r,v);  
    }  
    void build(ll &x)  
    {  
        cnt++;x=cnt;  
        scanf("%lld",&a[x]);  
        if (a[x])  
         {  
            addnew(rt[x],1,n,a[x]);  
            return;  
         }  
        build(CH[x][0]);  
        build(CH[x][1]);  
    }  
    ll merge(ll x,ll y)
    {  
        if (!x) return y;  
        if (!y) return x;  
        ans+=sum[ch[x][0]]*sum[ch[y][1]];  
        ch[x][0]=merge(ch[x][0],ch[y][0]);  
        ch[x][1]=merge(ch[x][1],ch[y][1]);  
        sum[x]=sum[ch[x][0]]+sum[ch[x][1]];  
        return x;  
    }  
    void dfs(ll x)  
    {  
        ll lc=CH[x][0],rc=CH[x][1];  
        if (a[x]) return;  
        dfs(lc);dfs(rc);  
        ll tot=sum[rt[lc]]*sum[rt[rc]];  
        ans=0;  
        rt[x]=merge(rt[lc],rt[rc]);  
        ANS+=min(ans,tot-ans);  
    }  
    int main()  
    {  
        scanf("%lld",&n);  
        ll root;  
        build(root);  
        dfs(root);  
        printf("%lld",ANS);  
    }  
  • 相关阅读:
    随机数表示方法
    何时用重定向何时用转发
    http中重定向和请求转发
    Java正则表达式
    自定义圆形的ProgressBar
    Android内存管理机制
    Android 安全机制
    8位颜色值的含义
    Shape使用
    Bitmap(三)
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8092601.html
Copyright © 2011-2022 走看看