题意:

传送门

给\(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. ELK一个优秀的日志收集、搜索、分析的解决方案

    1 什么是ELK? ELK,是Elastaicsearch.Logstash和Kibana三款软件的简称.Elastaicsearch是一个开源的全文搜索引擎.Logstash则是一个开源的数据收集引 ...

  2. 三分钟学会 ASP.NET Core WebApi使用Swagger生成api说明文档

    什么是Swagger?为啥要用Swagger? Swagger可以从不同的代码中,根据注释生成API信息,Swagger拥有强大的社区,并且对于各种语言都支持良好,有很多的工具可以通过swagger生 ...

  3. MySQL调优之分区表

    一.分区表的应用场景 1.为什么是用分区表? 表非常大以至于无法全部都放在内存中,或者只在表的最后部分有热点数据,其他均是历史数据,分区表是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理 ...

  4. Failed to start ssh.service: Unit not found.

    Failed to start ssh.service: Unit not found. 报错内容: [Centos7@localhost ~]$ service ssh start Redirect ...

  5. 中文电子病历命名实体识别(CNER)研究进展

    中文电子病历命名实体识别(CNER)研究进展 中文电子病历命名实体识别(Chinese Clinical Named Entity Recognition, Chinese-CNER)任务目标是从给定 ...

  6. get uuid

    https://wx2.qq.com/?&lang=zh_CN /** * 启动二维码登录 */ function doQrcodeLogin() { loginFactory.getUUID ...

  7. BootstrapValidator验证规则、BootStrap表格:列参数

    BootstrapValidator验证规则 需引用组件 <script src="~/Scripts/jquery-1.10.2.js"></script> ...

  8. centos6.5升级gcc 4.4.7为最新版4.9.1

    ==================本方法切实可行===桌面版不建议用.centos============================== 1.下载源码包 我的下载  gcc-4.9.1.tar ...

  9. Linux常用习惯和技巧

    1.如果有些命令在执行时不断地在屏幕上输出信息,影响到后续命令的输入,则可以在执行命令时在末尾添加上一个&符号,这样命令将进入系统后台来执行.

  10. 遇到的一个bug

    /// <summary> /// 检测玩家是否在机器人的球形碰撞体内,这个碰撞体是机器人的侦测范围,玩家在内部会进行视野检测和声音检测 /// </summary> priv ...