• CF1417E XOR Inverse(字典树上分治)


    题意:

    给出一个数组,询问最小的数x,使得数组里每个数异或这个x后,整个数组的逆序对数量最少。

    题解:

    /*
     *题意:
     *给出一个数组,询问一个最小的值x,使得这个数组的所有元素异或x后逆序对最少
     *考虑贪心做法,从低位到高位构造x
     *每次比较x的第i位是1和x的第i位是0所形成的数组的逆序对数量,选择少的那一个
     *可以将每个数的二进制形式高位到低位存到一个字典树里
     *两个数的大小取决于他们二进制位上第一个不同的位
     *可以单独考虑字典树的其中一个子树,设它的左子树为l,右子树为r,那么l里面的所有数一定是比r小的
     *可以枚举l里面有多少数的下标比r里面的数的下标小,这样一个子树内的逆序对数量就统计完了
     *然后将所有子树以此合并,最后根节点得到的是所有逆序数的数量
     
     *接下来考虑贪心构造x的这个过程
     *假设当前贪心到x的第i位,这一位是1,那么对应层数的子树要反转
     *开一个dp数组分别统计翻转和不翻转的逆序对数量
     *就完成了这个贪心的过程
     */ 
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=4e6+100;
    typedef long long ll;
    int n,Trie[maxn][2],tot;
    ll dp[maxn][2];
    vector<int> g[maxn];
    void add (int x,int p) {
        int u=0;
        for (int i=29;i>=0;i--) {
            int bit=((x>>i)&1);
            if (!Trie[u][bit]) Trie[u][bit]=++tot;
            u=Trie[u][bit];
            g[u].push_back(p);
        }
    }
    void dfs (int u,int dep) {
        if (Trie[u][0]) dfs(Trie[u][0],dep-1);
        if (Trie[u][1]) dfs(Trie[u][1],dep-1);
        if (!Trie[u][0]||!Trie[u][1]) return;
        ll sum=0;
        int tt=0;
        for (int i=0;i<g[Trie[u][0]].size();i++) {
            while (tt<g[Trie[u][1]].size()&&g[Trie[u][1]][tt]<g[Trie[u][0]][i]) tt++;
            sum+=tt;
        } 
        dp[dep][0]+=sum;
        dp[dep][1]+=(ll)g[Trie[u][0]].size()*g[Trie[u][1]].size()-sum;
    }
    void solve () {
        scanf("%d",&n);
        for (int i=1;i<=n;i++) {
            int x;
            scanf("%d",&x);
            add(x,i);
        }
        dfs(0,29);
        ll ans=0,u=0;
        for (int i=0;i<=29;i++) {
            ans+=min(dp[i][0],dp[i][1]);
            if (dp[i][1]<dp[i][0]) u+=(1<<i);
        }
        printf("%lld %lld
    ",ans,u);
    }
    int main () {solve();}
  • 相关阅读:
    计算机图形学的学习资源
    Matlab绘图基础
    Matlab绘图函数一览
    Matlab编程基础
    Python实现对文件夹内文本文件递归查找
    C++预处理详解
    C++的学习资源
    OGRE启动过程详解(OGRE HelloWorld程序原理解析)
    Bullet核心类介绍(Bullet 2.82 HelloWorld程序及其详解,附程序代码)
    windows下Bullet 2.82编译安装(Bullet Physics开发环境配置)
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/13744193.html
Copyright © 2020-2023  润新知