• UOJ681【UR #22】月球列车【二进制,Trie】


    给定 \(n\) 个自然数 \(a_1,\cdots,a_n\)\(m\) 次询问自然数 \(v\),求 \(\bigoplus_{i=1}^n(a_i+x)\) 的值。

    \(n,m\le 2.5\cdot 10^5\)\(0\le a_i,x<2^{60}\),强制在线。


    考虑暴力,设现在要求答案的第 \(j\) 位,而 \(a_i+v\) 的第 \(j\) 位即为 \(a_i\oplus v\) 的第 \(j\) 位异或上 \(a_i+v\) 的第 \(j-1\) 位是否进位,设 \(a'_{j,i}=a_i\&(2^{j+1}-1)\),后者也即 \(a'_{j-1,i}\ge 2^j-(v\&(2^j-1))\),对 \(a'_{j,i}\) 排序后二分即可,时间复杂度 \(O((n+m)\log n\log V)\)

    而排序预处理的部分可以利用上一次排序的结果:设对 \(j\) 预处理出的 \(a'_{j,i}\) 排序后的结果为 \(b_{j,1}\le\cdots\le b_{j,n}\),直接将 \(b_{j-1,i}\) 中第 \(j\) 位为 \(0,1\) 的分离即得 \(b_{j,i}\)

    考虑对二分过程也类似处理。预处理 \(s_{0/1,j,i}\) 表示 \(b_{j-1,1},\cdots,b_{j-1,i}\) 中有多少个第 \(j\) 位为 \(0/1\) 的,查询时从小到大枚举 \(j\),维护 \(x\) 表示满足上述不等式(第 \(j\) 位进位)的 \(i\) 的个数。

    • \(v\) 的第 \(j\) 位为 \(1\),则后 \(j\) 位进位时贡献为 \(s_{1,j,n}-s_{1,j,n-x}\),不进位时贡献为 \(s_{0,j,n-x}\),然后令 \(x:=n-s_{0,j,n-x}\)
    • \(v\) 的第 \(j\) 位为 \(0\),则后 \(j\) 位进位时贡献为 \(s_{0,j,n}-s_{0,j,n-x}\),不进位时贡献为 \(s_{1,j,n-x}\),然后令 \(x:=s_{1,j,n}-s_{1,j,n-x}\)

    时间复杂度 \(O((n+m)\log V)\),空间复杂度 \(O(n\log V)\)

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned long long LL;
    const int N = 250003;
    int n, m, op, p[N], t[2][N], s[61][N];
    LL a[N], v, ans;
    int main(){
        ios::sync_with_stdio(false);
        cin >> n >> m >> op;
        for(int i = 1;i <= n;++ i){cin >> a[i]; p[i] = i;}
        for(int i = 0;i < 61;++ i){
            t[0][0] = t[1][0] = 0;
            for(int j = 1;j <= n;++ j){
                bool x = a[p[j]]>>i&1;
                t[x][++t[x][0]] = p[j];
                s[i][j] = t[0][0];
            }
            for(int i = 1;i <= t[0][0];++ i) p[i] = t[0][i];
            for(int i = 1;i <= t[1][0];++ i) p[i+t[0][0]] = t[1][i];
        }
        while(m --){
            cin >> v; if(op) v ^= ans >> 20;
            int x = 0; ans = 0;
            for(int i = 0;i < 61;++ i)
                if(v >> i & 1){
                    ans |= ((x ^ s[i][n]) & 1ll) << i;
                    x = n - s[i][n-x];
                } else {
                    ans |= ((n ^ x ^ s[i][n]) & 1ll) << i;
                    x += s[i][n-x] - s[i][n];
                }
            printf("%llu\n", ans);
        }
    }
    
  • 相关阅读:
    caffe常用层: batchNorm层和scale层
    简述configure、pkg-config、pkg_config_path三者的关系
    python删除list中元素的三种方法
    Leetcode 872. Leaf-Similar Trees
    Leetcode 508. Most Frequent Subtree Sum
    Leetcode 572. Subtree of Another Tree
    Leetcode 894. All Possible Full Binary Trees
    Leetcode 814. Binary Tree Pruning
    Leetcode 557. Reverse Words in a String III
    python 多维list声明时的小问题
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/15695702.html
Copyright © 2020-2023  润新知