• 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;	
    }
    
  • 相关阅读:
    git 错误 fatal: Not a valid object name: 'master'.
    SQL: select一组数据,concat同表同列的数据
    Linux curl usage
    Regular Expression
    浅谈Linux Process status,环境锁
    浅谈Manpage
    Java文件读写详解。 附txt乱码问题, html乱码问题
    在ubuntu 18.04下装有线守护wg
    centOS 7 换ssh端口
    如何把DEBIAN变成UBUNTU-DESKTOP最少化安装
  • 原文地址:https://www.cnblogs.com/wyxdrqc/p/10645199.html
Copyright © 2020-2023  润新知