zoukankan      html  css  js  c++  java
  • bzoj2212 Tree Rotations

    被BZOJ坑了一下午,原以为是我程序有问题一直WA,结果是我数组小了。。。为啥不给我RE!!!

    线段树合并,对于逆序对而言,只能通过交换左右子树来达到,那么我们就可以想到对于一个结点而言,我们当然要取左右子树不叫换产生的逆序对,及交换产生的逆序对,取最小的就好了,另外呢,因为要维护子树中包含的数,在往上递归时需要对该树合并。

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<string>
    #include<set>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<list>
    #include<cmath>
    #include<cstring>
    #include<map>
    #include<stack>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define maxn 2000005
    #define ull unsigned long long
    #define ll long long
    #define hashmod 99999839
    #define mod 9997
    int n,x,y;
    int ls[maxn],rs[maxn];//结点的左右儿子
    int c[maxn],len;//结点代表的区间中有的个数
    long long ans,s;
    stack<int> st;
    int newnode(){//返回一个新结点
        int p;
        if(st.empty()) p = len++;
        else p = st.top(),st.pop();
        ls[p] = rs[p] = 0,c[p] = 1;
        return p;
    }
    int bulid(int x){//建立叶子结点对应的树并返回根
        int root = newnode();//先申请一个新节点
        int l = 1,r = n,mid,p = root;
        while(l < r){
            mid = (l + r) >> 1;
            if(mid >= x) ls[p] = newnode(),p = ls[p],r = mid;
            else rs[p] = newnode(),p = rs[p],l = mid + 1;
        }
        return root;
    }
    int merge(int p,int q){//合并以p,q为根的树,并返回新的根
        if(!p || !q) return p + q;
        s += (long long)c[rs[p]] * c[ls[q]];
        ls[p] = merge(ls[p],ls[q]);
        rs[p] = merge(rs[p],rs[q]);
        c[p] = c[ls[p]] + c[rs[p]];
        st.push(q);//可将合并了的q结点放入st中
        return p;
    }
    int solve(){
        scanf("%d",&x);
        if(x) return bulid(x);//对叶节点建立一颗线段树
        int p = solve(),q = solve();//建立其左右儿子
        ll t = c[p] * c[q];
        s = 0,p = merge(p,q);//逆序对由非叶子结点产生
        if(s <= t / 2) ans += s;
        else ans += t - s;
        return p;
    }
    void init(){
        while(!st.empty()) st.pop();
        len = 1,ans = 0;
    }
    int main(){
        freopen("a.in","r",stdin);
        freopen("b.out","w",stdout);
        scanf("%d",&n);
        init();
        solve();
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    896. Monotonic Array单调数组
    865. Smallest Subtree with all the Deepest Nodes 有最深节点的最小子树
    489. Robot Room Cleaner扫地机器人
    JavaFX
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
    《Python CookBook2》 第一章 文本
  • 原文地址:https://www.cnblogs.com/zhuiyicc/p/9537860.html
Copyright © 2011-2022 走看看