zoukankan      html  css  js  c++  java
  • bzoj 2212 Tree Rotations

    题目大意:

    一棵二叉树,所有非叶子节点都有两个孩子

    在每个叶子节点上有一个权值 可以任意交换每个非叶子节点的左右孩子

    要求进行一系列交换,使得最终所有叶子节点的权值按照顺序写出来,逆序对个数最少

    思路:

    建立权值线段树

    dfs时 对于每个节点 判断交换更好还是不交换好 再加上左右儿子的答案向上继续传递答案

    判断的时候merge

     1  
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<cstdlib>
     6 #include<cstring>
     7 #include<algorithm>
     8 #include<vector>
     9 #include<queue>
    10 #define inf 2139062143
    11 #define ll long long
    12 #define MAXN 400100
    13 using namespace std;
    14 inline int read()
    15 {
    16     int x=0,f=1;char ch=getchar();
    17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 int n,o,rt[MAXN],tot,ch[MAXN][2],val[MAXN],ls[MAXN<<5],rs[MAXN<<5];
    22 ll ansl,ansr,sum[MAXN<<5];
    23 void init(int &x)
    24 {
    25     if(!x) x=++tot;
    26     val[x]=read();
    27     if(!val[x]) {init(ch[x][0]);init(ch[x][1]);}
    28 }
    29 void mdf(int &k,int l,int r,int x)
    30 {
    31     k=++tot;
    32     if(l==r) {sum[k]=1;return ;}
    33     int mid=(l+r)>>1;
    34     if(x<=mid) mdf(ls[k],l,mid,x);
    35     else mdf(rs[k],mid+1,r,x);
    36     sum[k]=sum[ls[k]]+sum[rs[k]];
    37 }
    38 int merge(int a,int b)
    39 {
    40     if(!a||!b) return a+b;
    41     ansl+=sum[rs[a]]*sum[ls[b]];
    42     ansr+=sum[ls[a]]*sum[rs[b]];
    43     ls[a]=merge(ls[a],ls[b]);
    44     rs[a]=merge(rs[a],rs[b]);
    45     sum[a]=sum[ls[a]]+sum[rs[a]];
    46     return a;
    47 }
    48 ll dfs(int x)
    49 {
    50     ll res=0;
    51     if(!val[x])
    52     {
    53         res=dfs(ch[x][0])+dfs(ch[x][1]);
    54         ansl=ansr=0;
    55         rt[x]=merge(rt[ch[x][0]],rt[ch[x][1]]);
    56         res+=min(ansl,ansr);
    57     }
    58     else mdf(rt[x],1,n,val[x]);
    59     return res;
    60 }
    61 int main()
    62 {
    63     n=read();
    64     init(o);tot=0;
    65     printf("%lld",dfs(1));
    66 }
    View Code
  • 相关阅读:
    41.用c++编写程序:从键盘上任意输20个1-99之间的整数,分别统计其个位数0-9的数字各有多少
    【编程规范整理】
    CI/CD----jenkins+gitlab+django(内网)
    tomcat访问日志
    Django + celery +redis使用
    CI/CD----jenkins安装配置
    linux 批量删除进程
    django数据查询之聚合查询和分组查询
    django middleware介绍
    git初始化命令行指引
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9806715.html
Copyright © 2011-2022 走看看