zoukankan      html  css  js  c++  java
  • 题解 洛谷 P3521 【[POI2011]ROT-Tree Rotations】

    给定一棵二叉树,叶子节点有权值,可以进行若干次交换一个节点的左右儿子的操作,使前序遍历叶子的逆序对最少。

    考虑一个节点下子树逆序对的产生:

    ① 只在左子树中产生。

    ② 只在右子树中产生。

    ③ 在左子树和右子树中交叉产生。

    因为二叉树的性质,所以 ① ② 两种情况只需递归下去求解,只需考虑情况 ③ 。

    用权值线段树来记录信息,通过线段树合并来统计答案。

    具体实现细节看代码吧。

    记得开(long long)

    (code:)

    #include<bits/stdc++.h>
    #define maxn 10000010
    using namespace std;
    typedef long long ll;
    template<typename T> inline void read(T &x)
    {
    	x=0;char c=getchar();bool flag=false;
    	while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
    	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	if(flag)x=-x;
    }
    int n,root,tree_cnt;
    ll s1,s2,ans;
    bool vis[maxn];
    int ls[maxn],rs[maxn],rt[maxn];
    ll siz[maxn];
    void pushup(int cur)
    {
        siz[cur]=siz[ls[cur]]+siz[rs[cur]];
    }
    void modify(int L,int R,int pos,int &cur)
    {
        if(!cur) cur=++tree_cnt;
        if(L==R)
        {
            siz[cur]++;
            return;
        }
        int mid=(L+R)>>1;
        if(pos<=mid) modify(L,mid,pos,ls[cur]);
        if(pos>mid) modify(mid+1,R,pos,rs[cur]);
        pushup(cur);
    }
    int merge(int x,int y)
    {
        if(!x||!y) return x+y;
        s1+=siz[ls[x]]*siz[rs[y]];
        s2+=siz[ls[y]]*siz[rs[x]];
        ls[x]=merge(ls[x],ls[y]);
        rs[x]=merge(rs[x],rs[y]);
        pushup(x);
        return x;
    }
    void dfs(int &x)
    {
        int val;
        read(val);
        x=++tree_cnt;
        if(!val) dfs(ls[x]),dfs(rs[x]);
        else vis[x]=true,modify(1,n,val,rt[x]);
    }
    void work(int x)
    {
        if(vis[x]) return;
        work(ls[x]),work(rs[x]),s1=s2=0;
        rt[x]=merge(rt[ls[x]],rt[rs[x]]);
        ans+=min(s1,s2);
    }
    int main()
    {
    	read(n);
        dfs(root);
        work(root);
        printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    UIView
    UISwitch
    UIButton
    label标签的属性
    sublime 生成网页头文件
    Xcode快捷键
    Bootstrap 模态对话框只加载一次 remote 数据的解决办法 转载
    用谷歌浏览器来当手机模拟器
    DDD:谈谈数据模型、领域模型、视图模型和命令模型
    MoQ(基于.net3.5,c#3.0的mock框架)简单介绍
  • 原文地址:https://www.cnblogs.com/lhm-/p/12229829.html
Copyright © 2011-2022 走看看