• Xor Query [ABC223H]


    https://atcoder.jp/contests/abc223/tasks/abc223_h

    题解

    奇技淫巧。。。

    首先当然是想到了线性基 但是区间的限制怎么办呢?

    考虑固定右端点,对于线性基的每一位记录一个 (id) 表示这一位的值是从 (a_{id}) 来的

    每次加入一个 (a_i) 时,从大到小枚举第 (j) 位,如果 (a_i) 的第 (j) 位为 (1)

    如果线性基的第 (j) 位没有值就把它设为 (a_i) 并且跳出循环

    否则如果 (id_j < i) 就交换 (id_j,i),交换线性基第 (j) 位的值和 (a_i) ,然后继续枚举低位

    查询时只需要保证所有需要修改的位 (j) 都满足 (l le id_j) 即可

    实现和普通的异或线性基差别不大 见代码

    由于此篇题解比较垃圾所以没有证明,只是记录一下这个技巧(狗头)

    #include <bits/stdc++.h>
    #define N 400005
    using namespace std;
    typedef long long ll;
    
    template <typename T>
    inline void read(T &num) {
    	T x = 0, f = 1; char ch = getchar();
    	for (; ch > '9' || ch < '0'; ch = getchar()) if (ch == '-') f = -1;
    	for (; ch <= '9' && ch >= '0'; ch = getchar()) x = (x<<1) + (x<<3) + (ch^'0');
    	num = x * f;
    }
    
    int n, m;
    ll a[N][60]; int id[N][60];
    
    inline void upd(ll x, int p) {
    	int P = p;
    	for (int i = 60; ~i; i--) a[P][i] = a[P-1][i], id[P][i] = id[P-1][i];
    	for (int i = 60; ~i; i--) if ((x>>i)&1) {
    		if (!a[P][i]) {
    			a[P][i] = x; id[P][i] = p; break;
    		} else if (p > id[P][i]) {
    			swap(a[P][i], x); swap(id[P][i], p);
    		}
    		x ^= a[P][i];
    	}
    }
    
    int main() {
    	read(n); read(m);
    	for (int i = 1; i <= n; i++) {
    		ll x; read(x); upd(x, i);
    	}
    	while (m--) {
    		int l, r, ok = 1; ll x; read(l); read(r); read(x);
    		for (int i = 60; ~i; i--) if ((x>>i)&1) {
    			if (!a[r][i] || id[r][i] < l) { ok = 0; break; }
    			else x ^= a[r][i];
    		}
    		puts(ok?"Yes":"No");
    	}
    	return 0;
    }
    
    作者:AK_DREAM
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    mongodb的安装和sql操作
    查看apache和nginx的负载和连接数情况
    ansible中playbook使用
    mysql导入导出命令详解
    生产环境下yum的配置
    firewalld的防火墙
    SOCK5代理服务器
    Linux系统基础优化总结
    服务器内存和缓存的优化
    activemq概念介绍
  • 原文地址:https://www.cnblogs.com/ak-dream/p/AK_DREAM124.html
Copyright © 2020-2023  润新知