题意:

传送门

给\(n\)个集合,每个集合有一些数。给出\(m\)个询问,再给出\(l\)和\(r\)和一个数\(v\),问你任意的\(i \in[l,r]\)的集合,能不能找出子集异或为\(v\)。简单点说,\(v\)能用\([l,r]\)任意一个集合的子集异或和表示。

思路:

子集异或和显然是用线性基。我们用线段树维护任意区间的线性基交集即可。

代码:

/**
求交集 O(logn * logn)
**/
LBasis intersection(const LBasis &a, const LBasis &b){
LBasis ans, c = b, d = b;
ans.init();
for (int i = 0; i <= 32; i++){
ll x = a.d[i];
if(!x)continue;
int j = i;
ll T = 0;
for(; j >= 0; --j){
if((x >> j) & 1)
if(c.d[j]) {x ^= c.d[j]; T ^= d.d[j];}
else break;
}
if(!x) ans.d[i] = T;
else {c.d[j] = x; d.d[j] = T;}
}
return ans;
}
#include<map>
#include<set>
#include<cmath>
#include<cstdio>
#include<stack>
#include<ctime>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = 50000 + 5;
const int INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
using namespace std; struct LBasis{
ll d[33];
int tot;
void init(){
memset(d, 0, sizeof(d));
tot = 0;
}
bool insert(ll x){
for(int i = 32; i >= 0; i--){
if(x & (1LL << i)){
if(d[i]) x ^= d[i];
else{
d[i] = x;
return true;
}
}
}
return false;
} bool checkin(ll x){
for(int i = 32; i >= 0; i--){
if(x & (1LL << i)){
if(d[i]) x ^= d[i];
else return false;
}
}
return true;
} };
LBasis intersection(const LBasis &a, const LBasis &b){
LBasis ans, c = b, d = b;
ans.init();
for (int i = 0; i <= 32; i++){
ll x = a.d[i];
if(!x)continue;
int j = i;
ll T = 0;
for(; j >= 0; --j){
if((x >> j) & 1)
if(c.d[j]) {x ^= c.d[j]; T ^= d.d[j];}
else break;
}
if(!x) ans.d[i] = T;
else {c.d[j] = x; d.d[j] = T;}
}
return ans;
}
LBasis node[maxn << 2];
void pushup(int rt){
node[rt] = intersection(node[rt << 1], node[rt << 1 | 1]);
}
void build(int l, int r, int rt){
if(l == r){
int sz;
scanf("%d", &sz);
node[rt].init();
while(sz--){
ll x;
scanf("%lld", &x);
node[rt].insert(x);
}
return;
}
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 1);
pushup(rt);
}
bool query(int L, int R, int l, int r, ll v, int rt){
if(L <= l && R >= r){
return node[rt].checkin(v);
}
int m = (l + r) >> 1;
bool ok = true;
if(L <= m)
ok = ok && query(L, R, l, m, v, rt << 1);
if(R > m)
ok = ok && query(L, R, m + 1, r, v, rt << 1 | 1);
return ok;
}
int main(){
int n, m;
scanf("%d%d", &n, &m);
build(1, n, 1);
while(m--){
int l, r;
ll x;
scanf("%d%d%lld", &l, &r, &x);
if(query(l, r, 1, n, x, 1)) printf("YES\n");
else printf("NO\n");
}
return 0;
}

2019牛客多校第四场B xor(线性基求交)题解的更多相关文章

  1. 2019牛客多校第四场B xor——线段树&&线性基的交

    题意 给你 $n$ 个集合,每个集合中包含一些整数.我们说一个集合表示一个整数当且仅当存在一个子集其异或和等于这个整数.现在你需要回答 $m$ 次询问 ($l, r, x$),是否 $l$ 到 $r$ ...

  2. 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数

    目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...

  3. 2019牛客多校第四场 A meeting

    链接:https://ac.nowcoder.com/acm/contest/884/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语言10485 ...

  4. 2019牛客多校第四场J free——分层图&&最短路

    题意 一张无向图,每条边有权值,可以选择不超过 $k$ 条路使其权值变成0,求 $S$ 到 $T$ 的最短路.(同洛谷 P4568) 分析 首先,分层图最短路可以有效解决这种带有 「阶段性」的最短路, ...

  5. 2019牛客多校第四场A meeting——树的直径

    题意: 一颗 $n$ 个节点的树上标有 $k$ 个点,找一点使得到 $k$ 个关键结点的最大距离最小. 分析: 问题等价于求树的直径,最小距离即为直径除2向上取整. 有两种求法,一是动态规划,对于每个 ...

  6. [2019牛客多校第四场][G. Tree]

    题目链接:https://ac.nowcoder.com/acm/contest/884/G 题目大意:给定一个树\(A\),再给出\(t\)次询问,问\(A\)中有多少连通子图与树\(B_i\)同构 ...

  7. 2019牛客多校第四场D-triples I 贪心

    D-triples 题意 给你一个\(n\),问至少有几个数或运算起来可以等于\(n\),并且输出数量和这个几个数.题目说明给的\(n\)一定符合条件(不会输出\(n= 1\) 之类不存在情况). 思 ...

  8. 2019牛客多校第四场C-sequence(单调栈+线段树)

    sequence 题目传送门 解题思路 用单调栈求出每个a[i]作为最小值的最大范围.对于每个a[i],我们都要乘以一个以a[i]为区间内最小值的对应的b的区间和s,如果a[i] > 0,则s要 ...

  9. 2019牛客多校第四场K number dp or 思维

    number 题意 给一个数字串,问有几个子串是300的倍数 分析 dp写法:这题一看就很dp,直接一个状态dp[i][j]在第i位的时候膜300的余数是j左过去即可.这题比赛的时候样例老是少1,后面 ...

随机推荐

  1. 解决ubuntu获取root账号并开通ssh

    1.设置root密码 sudo passwd root 2.修改etc/ssh/sshd_config文件 su - root vi /etc/ssh/sshd_config LoginGraceTi ...

  2. 太极图HTML+CSS(可旋转)代码记录

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. Spider爬虫基础

    get获取某个网站的html代码,post访问网站获取网站返回的信息 import urllib.request import urllib.parse #使用get请求 def start1(): ...

  4. java虚拟机入门(一)-jvm基础

    转行学java之前,总是听着大佬们说着java像个渣男一样可以跨平台,一次编译到处运行,瞬间,我就坚定了学java的信念,哎呀妈呀,得劲.真的学java之后,好像渣男也不是那么好学的,尤其这货的必杀技 ...

  5. CUDA 介绍

    1. 介绍 1.1 GPU vs. CPU GPU 使用更多的晶体管进行数据处理,而不是数据缓存和流控制,因此可以提供高度的并行计算. GPU 可以通过计算来隐藏内存访问延迟,而不是依赖于大量的数据缓 ...

  6. Unix Socket 代理服务 unix域套接字

    基于Unix Socket的可靠Node.js HTTP代理实现(支持WebSocket协议) - royalrover - 博客园 https://www.cnblogs.com/accordion ...

  7. 深入理解 MySQL 索引底层原理

    https://mp.weixin.qq.com/s/qHJiTjpvDikFcdl9SRL97Q

  8. based on Greenlets (via Eventlet and Gevent) fork 孙子worker 比较 gevent不是异步 协程原理 占位符 placeholder (Future, Promise, Deferred) 循环引擎 greenlet 没有显式调度的微线程,换言之 协程

    gevent GitHub - gevent/gevent: Coroutine-based concurrency library for Python https://github.com/gev ...

  9. LOJ10097和平委员会

    POI 2001 根据宪法,Byteland民主共和国的公众和平委员会应该在国会中通过立法程序来创立. 不幸的是,由于某些党派代表之间的不和睦而使得这件事存在障碍. 此委员会必须满足下列条件: 每个党 ...

  10. Linux 输入输出重定向, &>file, 2>&1, 1>&2

    Linux 输入输出重定向, &>file, 2>&1, 1>&2 一.1和2在Linux中代表什么 1.1 输出重定向 1.2 输入重定向 1.3 绑定重定 ...