• Codeforces 1322B


    Description

    给出序列 $a_i$, 求两两之和的异或值 


    Solution

    按位计算
    计算到第 $k$ 位时,将 $a_i$ 按 $mod 2^{k+1}$ 后排序
    当 $a_i mod 2^{k+1} + a_j mod 2^{k+1}in [2^k, 2^{k+1} - 1] cup [2^{k + 1} + 2^k, 2^{k+2}-2]$, 这两数和的第 $k$ 位为 $1$
    排序时每次加入一位重排可用归并排序,找区间可以用双指针
    复杂度$O(n log Max)$


    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    
    inline int read() {
        int out = 0;
        bool flag = false;
        register char cc = getchar();
        while (cc < '0' || cc > '9') {
            if (cc == '-') flag = true;
            cc = getchar();
        }
        while (cc >= '0' && cc <= '9') {
            out = (out << 3) + (out << 1) + (cc ^ 48);
            cc = getchar();
        }
        return flag ? -out : out;
    } 
    
    inline void write(int x) {
        if (x < 0) putchar('-'), x = -x;
        if (x == 0) putchar('0');
        else {
            int num = 0;
            char cc[15];
            while (x) cc[++num] = x % 10 + 48, x /= 10;
            while (num) putchar(cc[num--]);
        }
        putchar('
    ');
    }
    
    
    int N, a[400010], b[400010], l1, r1, l2, r2, cnt, ans;
    
    queue<int> q1, q2; 
    
    int main() {
        N = read();
        for (int i = 1; i <= N; i++) a[i] = read(), b[i] = i;
        for (int k = 0; k <= 24; k++) {
            for (int i = 1; i <= N; i++) 
                if (a[b[i]] & (1 << k)) q1.push(b[i]);
                else q2.push(b[i]);
            int o = 0; 
            while (!q2.empty()) b[++o] = q2.front(), q2.pop();
            while (!q1.empty()) b[++o] = q1.front(), q1.pop();
            l1 = l2 = N + 1, r1 = r2 = N, cnt = 0;
            int Mod = (1 << (k + 1)) - 1;
            for (int i = 1; i <= N; i++) {
                o = (a[b[i]] & Mod);
                while (l1 >= 2 && o + (a[b[l1 - 1]] & Mod) >= (1 << k)) l1--;
                while (r1 >= 1 && o + (a[b[r1]] & Mod) >= (1 << (k + 1))) r1--;
                while (l2 >= 2 && o + (a[b[l2 - 1]] & Mod) >= (1 << (k + 1)) + (1 << k)) l2--;
                while (r2 >= 1 && o + (a[b[r2]] & Mod) >= (1 << (k + 2)) - 1) r2--;
                if (max(i + 1, l1) <= r1) cnt += r1 - max(i + 1, l1) + 1;
                if (max(i + 1, l2) <= r2) cnt += r2 - max(i + 1, l2) + 1;
            }
            if (cnt & 1) ans |= 1 << k;
        }
        write(ans);
        return 0;
    }
    View Code
  • 相关阅读:
    java线程
    windows Server 安装
    nginx正则反向代理
    crontab定时任务启动脚本失败
    数据结构
    异常概念
    shell日期遍历复制文件
    多态和抽象
    图1 列出连通集
    PTA 代码注意事项
  • 原文地址:https://www.cnblogs.com/Urushibara-Ruka/p/13124428.html
Copyright © 2020-2023  润新知