zoukankan      html  css  js  c++  java
  • bzoj 2212 : [Poi2011]Tree Rotations (线段树合并)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2212

    思路:用线段树合并求出交换左右儿子之前之后逆序对的数量,如果数量变小则交换.

    实现代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int M = 4e5+10;
    int n,cnt,idx;
    ll ans,cnt1,cnt2;
    int v[M],l[M],r[M],root[M];
    int sum[M*10],ls[M*10],rs[M*10];
    void init_tree(int x){
        scanf("%d",&v[x]);
        if(!v[x]){
            l[x] = ++cnt;
            init_tree(l[x]);
            r[x] = ++cnt;
            init_tree(r[x]);
        }
    }
    
    void pushup(int rt){
        sum[rt] = sum[ls[rt]] + sum[rs[rt]];
    }
    
    void build(int p,int l,int r,int &rt){
        if(!rt) rt = ++idx;
        if(l == r){
            sum[rt] = 1;
            return ;
        }
        int mid = (l + r) >> 1;
        if(p <= mid) build(p,l,mid,ls[rt]);
        else build(p,mid+1,r,rs[rt]);
        pushup(rt);
    }
    
    int merge(int x,int y){
        if(!x) return y;
        if(!y) return x;
        cnt1 += (ll)sum[rs[x]]*sum[ls[y]];
        cnt2 += (ll)sum[ls[x]]*sum[rs[y]];
        ls[x] = merge(ls[x],ls[y]);
        rs[x] = merge(rs[x],rs[y]);
        pushup(x);
        return x;
    }
    
    void solve(int x){
        if(!x) return ;
        solve(l[x]); solve(r[x]);
        if(!v[x]){
            cnt1 = cnt2 = 0;
            root[x] = merge(root[l[x]],root[r[x]]);
            ans += min(cnt1,cnt2);
        }
    }
    
    int main()
    {
        scanf("%d",&n);
        cnt = 1;
        init_tree(1);
        for(int i = 1;i <= cnt;i ++){
            if(v[i])
                build(v[i],1,n,root[i]);
        }
        solve(1);
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    1295: [SCOI2009]最长距离
    [vijos p1028] 魔族密码
    HJ浇花
    1060: [ZJOI2007]时态同步
    1816: [Cqoi2010]扑克牌
    1800: [Ahoi2009]fly 飞行棋
    4300: 绝世好题
    1237: [SCOI2008]配对
    1801: [Ahoi2009]chess 中国象棋
    1189: [HNOI2007]紧急疏散evacuate
  • 原文地址:https://www.cnblogs.com/kls123/p/9550227.html
Copyright © 2011-2022 走看看