题意:

传送门

给\(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. SP338 ROADS

    题目描述 城市中有R条有向马路,n个马路连接点,通过每条马路都要花去一定费用.你现在在编号为1的连接点 ,手里有k元钱,要去n号连接点的最短路径的长度是多少?途中经过道路的花费不能超过k.注意:两个 ...

  2. [Usaco2007 Jan]Balanced Lineup 飞盘比赛

    题目描述 每天,农夫 John 的N(1 <= N <= 50,000)头牛总是按同一序列排队. 有一天, John 决定让一些牛们玩一场飞盘比赛. 他准备找一群在对列中为置连续的牛来进行 ...

  3. 干电池升压3.3V的电源芯片

    PW5100适用于一节干电池升压到3.3V,两节干电池升压3.3V的升压电路,PW5100干电池升压IC. 干电池1.5V和两节干电池3V升压到3.3V的测试数据 两节干电池输出500MA测试: PW ...

  4. 使用Azure Runbook 发送消息到Azure Storage Queue

    客户需要定时发送信息到Azure Storage Queue,所以尝试使用Azure Runbook实现这个需求. 首先新增一个Azure Automation Account的资源. 因为要使用Az ...

  5. ovs-vsctl命令

    ovs-vsctl [options] -- [options] command [args] [-- [options] command [args]]... 通过连接到 ovsdb-server ...

  6. Crunch

    Crunch 目录 1. 简介 2. 命令格式 3. options可选参数 3.1 -b number[type] 3.2 -c number 3.3 -d numbersymbol 3.4 -e ...

  7. git branch --set-upstream-to=

    test@uat:/usr/server/app_server# git config --local -lcore.repositoryformatversion=0core.filemode=tr ...

  8. java的几种对象(PO,VO,DAO,BO,POJO)

    一.PO persistant object 持久对象,可以看成是与数据库中的表相映射的java对象.最简单的PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合.PO中应该不包含任何对数 ...

  9. Java——Number类

    在平时学习中,当我们需要使用数字的时候,通常使用内置数据类型,如byte,int,long,double等. int i =12; float a = 12.3; 在实际开发中,经常会遇到需要使用对象 ...

  10. 报表生成工具ireport

    最近又开始学习新的玩意儿了,扒拉扒拉网上的资源,先捣鼓个思维导图.