zoukankan      html  css  js  c++  java
  • BZOJ 3702 二叉树

    3702: 二叉树

    Time Limit: 15 Sec  Memory Limit: 256 MB
    Submit: 665  Solved: 307
    [Submit][Status][Discuss]

    Description

    现在有一棵二叉树,所有非叶子节点都有两个孩子。在每个叶子节点上有一个权值(有n个叶子节点,满足这些权值为1..n的一个排列)。可以任意交换每个非叶子节点的左右孩子。
    要求进行一系列交换,使得最终所有叶子节点的权值按照中序遍历写出来,逆序对个数最少。

    Input

    第一行n
    下面每行,一个数x
    如果x==0,表示这个节点非叶子节点,递归地向下读入其左孩子和右孩子的信息,
    如果x!=0,表示这个节点是叶子节点,权值为x。

    Output

    一行,最少逆序对个数。

    Sample Input

    3
    0
    0
    3
    1
    2

    Sample Output

    1

    HINT

    对于100%的数据:2<=n<=200000。

    Source

    直接上线段树合并即可

    https://www.cnblogs.com/Mychael/p/8665589.html

    /**************************************************************
        Problem: 3702
        User: zhangenming
        Language: C++
        Result: Accepted
        Time:7324 ms
        Memory:86028 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    #define ll long long
    #define inf 1e9+10
    #define ull unsigned long long
    #define eps 1e-7
    using namespace std;
    inline int read(){
        int x=0;int f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int MAXN=1e6+10;
    struct sig{
        int sum,ls,rs;
    }T[MAXN<<2];
    int rt[MAXN],n,l[MAXN],r[MAXN],vl[MAXN],tot,siz;
    ll sum1,sum2,ans;
    inline void build(int &x){
        int t=read();x=++tot;
        if(t==0) build(l[x]),build(r[x]);
        else vl[x]=t;
    }
    inline void ins(int l,int r,int &rt,int t){
        if(!rt) rt=++siz;
        T[rt].sum++;
        if(l==r) return;
        int mid=(l+r)>>1;
        if(t<=mid) ins(l,mid,T[rt].ls,t);
        else ins(mid+1,r,T[rt].rs,t);
    }
    inline int merge(int x,int y){
        if(!x||!y) return x+y;
        sum1+=1LL*T[T[x].rs].sum*T[T[y].ls].sum;
        sum2+=1LL*T[T[x].ls].sum*T[T[y].rs].sum;
        T[x].sum+=T[y].sum;
        T[x].ls=merge(T[x].ls,T[y].ls);
        T[x].rs=merge(T[x].rs,T[y].rs);
        return x;
    }
    inline void dfs(int x){
        if(vl[x]){
            ins(1,n,rt[x],vl[x]);
        }
        else{
            dfs(l[x]);dfs(r[x]);
            sum1=sum2=0;
            rt[x]=merge(rt[l[x]],rt[r[x]]);
            ans+=min(sum1,sum2);
        }
    }
    int main(){
        n=read();
        int root;
        build(root);
        dfs(root);
        printf("%lld
    ",ans);
        return 0;
    }
    
    

      

  • 相关阅读:
    泛型的二阶构造
    二叉树的优势
    浅谈AVL树,红黑树,B树,B+树原理及应用
    AVL树,红黑树,B树,B+树,Trie树都分别应用在哪些现实场景中?
    据库索引及其数据结构
    关系型数据库工作原理-数据结构(3)
    数据库的最简单实现
    为什么使用数据库?数据库的存取效率如何保证?
    iOS原生数据存储策略
    数据存储要解决的几个问题
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/9509305.html
Copyright © 2011-2022 走看看