zoukankan      html  css  js  c++  java
  • LuoguP3521 [POI2011]ROT-Tree Rotations

    P3521 [POI2011]ROT-Tree Rotations

    题目大意:

    给一棵((1≤n≤200000))个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少。

    我们发现交换两个子树并不会影响某个子树内的逆序对个数,只会对两个子树之间的逆序对产生影响.

    所以我们将换与不换的逆序对求出来,取个最小值

    将两颗线段树合并就好了

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cctype>
    #include<algorithm>
    #define LL long long
    using namespace std;
    const int N = 4e5 + 3;
    struct node{
        int sum;
        int lc,rc;	
    }a[N * 30];
    int root;
    int n,t,cnt = 1;
    int rt[N];
    LL ans1,ans2,ans;
    inline int read(){
        int v = 0,c = 1;char ch = getchar();
        while(!isdigit(ch)){
            if(ch == '-') c = -1;
            ch = getchar();	
        }
        while(isdigit(ch)){
            v = v * 10 + ch - 48;
            ch = getchar();	
        }
        return v * c;
    }
    inline void pushup(int u){
        a[u].sum = a[a[u].lc].sum + a[a[u].rc].sum;
    }
    inline void ins(int &u,int l,int r,int x){
    //	printf("%d %d %d
    ",l,r,x);
        if(!u) u = ++t;	
        if(l == r){
            a[u].sum++;
            return ;	
        }
        int mid = (l + r) >> 1;
        if(x <= mid) ins(a[u].lc,l,mid,x);
        else ins(a[u].rc,mid + 1,r,x);
        pushup(u);
    }
    inline void merge(int &u1,int u2,int l,int r){
        if(!u1){u1 = u2;return ;}
        if(!u2) return ;
        if(l == r){
            a[u1].sum += a[u2].sum;
            return ;
        }
        int mid = (l + r) >> 1;
        ans1 += 1ll * a[a[u1].lc].sum * a[a[u2].rc].sum;
        ans2 += 1ll * a[a[u2].lc].sum * a[a[u1].rc].sum;
        merge(a[u1].lc,a[u2].lc,l,mid);
        merge(a[u1].rc,a[u2].rc,mid + 1,r);
        pushup(u1); 
    }
    inline void solve(int pos){
        int x = read();
        if(!x){
        	int lc = ++cnt;solve(lc);
            int rc = ++cnt;solve(rc);
            merge(rt[pos],rt[lc],1,n);
            ans1 = ans2 = 0;
            merge(rt[pos],rt[rc],1,n);
            ans += min(ans1,ans2);
        }
        else{
            ins(rt[pos],1,n,x);
            return ;	
        }
    }
    int main(){
        n = read();
        solve(1);
        printf("%lld
    ",ans);
        return 0;	
    }
    
  • 相关阅读:
    centos redis 安装 php-redis扩展安装 及使用
    mysql 大数据分页查询优化
    nginx https ssl 配置
    mysql 集群 数据同步
    linux 挂载U盘
    centos yum 没有可用软件包 nginx。
    nginx 负载均衡 反向代理
    nginx 配置
    mac 多php版本安装
    Foundation框架
  • 原文地址:https://www.cnblogs.com/wyxdrqc/p/10645199.html
Copyright © 2011-2022 走看看