zoukankan      html  css  js  c++  java
  • [POI2011]ROT-Tree Rotations

    发现x的子树在后续处理中不会影响逆序对的情况(只关心有哪些值,相对位置已经不重要了)

    f[x]表示x为根的子树最小逆序对数

    考虑左右儿子交换与否。

    暴力是O(n^2)的

    考虑线段树合并

    左右儿子线段树合并的时候,直接类似于分治,记录另一棵数小于某个数的个数,

    选择代价小的放在前面

    具体看代码:

    1.x,y别写错。。。

    2.开long long,而且线段树可能存在一个点的sz大于n,乘起来会爆int

    #include<bits/stdc++.h>
    #define reg register int
    #define mid ((l+r)>>1)
    #define il inline
    #define numb (ch^'0')
    using namespace std;
    typedef long long ll;
    il void rd(int &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    namespace Miracle{
    const int N=200000+5;
    int n,ch[2*N][2];
    struct tr{
        int ls,rs;
        int sz;
    }t[40*N];
    int tot;
    void pushup(int x){
        t[x].sz=t[t[x].ls].sz+t[t[x].rs].sz;
    }
    ll xfsz,yfsz;
    int rt[2*N],m;
    ll f[2*N];
    int merge(int x,int y,int l,int r){
        if(!x||!y) return x+y;
        if(l==r){
            t[x].sz+=t[y].sz;
            return x;    
        }
        xfsz+=(ll)t[t[x].rs].sz*t[t[y].ls].sz;
        yfsz+=(ll)t[t[y].rs].sz*t[t[x].ls].sz;
        t[x].ls=merge(t[x].ls,t[y].ls,l,mid);
        t[x].rs=merge(t[x].rs,t[y].rs,mid+1,r);
        pushup(x);
        return x;
    }
    void upda(int &x,int l,int r,int p){
        if(!x) x=++tot;
        if(l==r){
            t[x].sz=1;
            return;
        }
        if(p<=mid) upda(t[x].ls,l,mid,p);
        else upda(t[x].rs,mid+1,r,p);
        pushup(x);
    }
    void build(int &x){
        x=++m;
        int val;rd(val);
        if(val==0){
            build(ch[x][0]);build(ch[x][1]);
        }else{
            upda(rt[x],1,n,val);
        }
    }
    void dfs(int x){
        if(ch[x][0]&&ch[x][1]){
            dfs(ch[x][0]),dfs(ch[x][1]);
        //    cout<<" back to "<<x<<endl;
            xfsz=0;yfsz=0;
            rt[x]=rt[ch[x][0]];
            rt[x]=merge(rt[x],rt[ch[x][1]],1,n);
            f[x]=f[ch[x][0]]+f[ch[x][1]]+min(xfsz,yfsz);
        //    cout<<" xfsz "<<xfsz<<" yfsz "<<yfsz<<endl;
        //    cout<<" f[x] "<<f[x]<<endl;
        }
    }
    int main(){
        rd(n);
        int haha;
        build(haha);
        dfs(1);
        printf("%lld
    ",f[1]);
        return 0;
    }
    
    }
    signed main(){
    //    freopen("4.in","r",stdin);
    //    freopen("4.out","w",stdout);
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2019/2/10 11:57:09
    */
  • 相关阅读:
    互联网预言大神:凯文·凯利——预测未来的12个趋势
    仅有算法远远不够:AI突破下一站,需要对硬件重新审视
    软件开发中经常使用的5种设计模式
    强化学习到底是什么,它如何运作?
    2020年网络安全的六大经验教训
    选择困难终结者:不同问题之下的机器学习算法
    为什么物联网如此重要?
    Pku3080 Blue Jeans
    pku1734 Musical Theme
    [Usaco2006 Dec]Milk Patterns
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10359309.html
Copyright © 2011-2022 走看看