zoukankan      html  css  js  c++  java
  • BZOJ2212【POI2011】ROT:Tree Rotation 线段树合并

    题意:

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

    分析:

      求逆序对我们可以想到权值线段树,所以我们对每个点建一颗线段树(为了避免空间爆炸,采取动态开点的科技)

      两个子节点可以交换,于是我们可以递归,自底向上贪心解决问题,每次线段树合并,在合并时,统计交换左右子节点后,横跨当前位置的逆序对数量,以及不交换子节点的情况下的这个数量,将更优的计入答案。这道问题就圆满解决了。

    代码:

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int N=2000005;
     5 struct node{ll v;int ls,rs;}t[N*4];
     6 int n,m,tot=0,cnt=1,nm[N],ls[N],rs[N],rt[N];
     7 ll ans=0,ans1,ans2;
     8 void read(int x){
     9     scanf("%d",&nm[x]);
    10     if(!nm[x]) read(ls[x]=++cnt),
    11     read(rs[x]=++cnt);return ;
    12 } void update(int &x,int l,int r,int v){
    13     if(!x) x=++tot;int mid=l+r>>1;
    14     if(l==r){t[x].v=1;return ;}
    15     if(v<=mid) update(t[x].ls,l,mid,v);
    16     else update(t[x].rs,mid+1,r,v);
    17     t[x].v=t[t[x].rs].v+t[t[x].ls].v;
    18 } int merge(int x,int y){
    19     if(!x||!y) return x|y;
    20     ans1+=(ll)t[t[x].rs].v*t[t[y].ls].v;
    21     ans2+=(ll)t[t[x].ls].v*t[t[y].rs].v;
    22     t[x].ls=merge(t[x].ls,t[y].ls);
    23     t[x].rs=merge(t[x].rs,t[y].rs);
    24     t[x].v=t[t[x].ls].v+t[t[x].rs].v;
    25     return x;
    26 } void dfs(int x){
    27     if(!x) return ;
    28     dfs(ls[x]);dfs(rs[x]);
    29     if(!nm[x]){
    30         ans1=ans2=0;
    31         rt[x]=merge(rt[ls[x]],rt[rs[x]]);
    32         ans+=min(ans1,ans2);
    33     } return ;
    34 } int main(){
    35     scanf("%d",&n);read(1);
    36     for(int i=1;i<=cnt;i++)
    37     if(nm[i]) update(rt[i],1,n,nm[i]);
    38     dfs(1);printf("%lld
    ",ans);
    39     return 0;
    40 }
    线段树合并
  • 相关阅读:
    Android Studio使用教程(一)
    Android Studio设置字体
    Android Studio设置字体
    8.8 Deep Learning Software
    梯度下降法与牛顿迭代法 求拟合参数
    什么是Condition Number(条件数)?
    什么是卷积?
    SLAM数据集
    TensorFlow安装教程
    Caffe
  • 原文地址:https://www.cnblogs.com/Alan-Luo/p/10391705.html
Copyright © 2011-2022 走看看