题意

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

分析

先求出每个集合的线性基,然后用线段树维护线性基的交,详见代码

  1. #include<bits/stdc++.h>
  2. #define reg register
  3. using namespace std;
  4. typedef long long ll;
  5.  
  6. const int bits = ;
  7. const int maxn = + ;
  8. int n, q;
  9. ll a[maxn][];
  10.  
  11. struct LBase {
  12. //const static int bits = 31; //0~31位
  13. ll d[bits+], tmp[bits+]; //线性基
  14. bool flag = false; //记录是否cnt < n
  15. LBase() {memset(d, , sizeof d);}
  16. void insert(ll x)
  17. {
  18. for(int i=bits;~i;i--)
  19. if(x&(1ll<<i))
  20. {
  21. if(!d[i]){ d[i]=x; break;}
  22. else x ^= d[i];
  23. }
  24. flag = true;
  25. }
  26. bool check(ll x) //返回true表示已经能被表示
  27. {
  28. for(int i=bits;~i;i--)
  29. if(x&(1ll<<i))
  30. {
  31. if(!d[i]) return false;
  32. else x ^= d[i];
  33. }
  34. return true;
  35. }
  36. ll qmax(ll res=)
  37. {
  38. for(int i=bits;~i;i--)
  39. res=max(res,res^d[i]);
  40. return res;
  41. }
  42. ll qmin()
  43. {
  44. if(flag) return ;
  45. for(int i=;i<=bits;i++)
  46. if(d[i]) return d[i];
  47. }
  48. ll query(ll k) //查询第k小
  49. {
  50. ll res=; int cnt=;
  51. k-=flag; if(!k)return ;
  52. for(int i=;i<=bits;i++){
  53. for(int j=i-;~j;j--)
  54. if(d[i]&(1ll<<j)) d[i]^=d[j];
  55. if(d[i]) tmp[cnt++]=d[i];
  56. }
  57. if(k>=(1ll<<cnt))return -;
  58. for(int i=;i<cnt;i++)
  59. if(k&(1ll<<i)) res^=tmp[i];
  60. return res;
  61. }
  62. void merge(const LBase &a) { //求并集
  63. for (int i = bits; i >= ; --i)
  64. if (a.d[i]) insert(a.d[i]);
  65. }
  66. };
  67.  
  68. LBase intersection(const LBase &a,const LBase &b) //求交集
  69. {
  70. LBase ans, c=b,d=b;
  71. for(int i = ;i <= bits;i++)
  72. {
  73. ll x =a.d[i];
  74. if(!x) continue;
  75. int j=i;ll T=;
  76. for(;j>=;--j)
  77. if((x>>j)&)
  78. if(c.d[j]){x^=c.d[j];T^=d.d[j];}
  79. else break;
  80. if(!x)ans.d[i]=T;
  81. else {c.d[j]=x;d.d[j]=T;}
  82. }
  83. return ans;
  84. }
  85.  
  86. struct SegTree
  87. {
  88. LBase b[maxn << ];
  89. void build(int o, int L, int R)
  90. {
  91. int M = L + (R-L) / ;
  92. if(L == R)
  93. {
  94. for(int i = ;i < ;i++) b[o].insert(a[L][i]);
  95. }
  96. else
  97. {
  98. build(*o, L, M);
  99. build(*o+, M+, R);
  100. //b[o].merge(b[2*o]); b[o].merge(b[2*o+1]);
  101. b[o] = intersection(b[*o], b[*o+]);
  102. }
  103. }
  104.  
  105. //查询[ql, qr]中是否都能表示出x
  106. bool query(int o,int L,int R, int ql, int qr, ll x)
  107. {
  108. int M = L + (R - L) / ;
  109. bool flag1 = true, flag2 = true;
  110. if(ql <= L && R <= qr) return b[o].check(x);
  111. if(ql <= M) flag1 = query(*o, L, M, ql, qr, x);
  112. if(qr > M) flag2 = query(*o+, M+, R, ql, qr, x);
  113. return flag1 && flag2;
  114. }
  115.  
  116. }seg;
  117.  
  118. int main(){
  119. scanf("%d%d", &n, &q);
  120. for(int i = ;i <= n;i++)
  121. {
  122. int sz; scanf("%d", &sz);
  123. for(int j = ;j < sz;j++) scanf("%lld", &a[i][j]);
  124. for(int j=sz; j < ;j++) a[i][j] = ;
  125. }
  126. seg.build(, , n);
  127. while(q--)
  128. {
  129. int l, r; ll x;
  130. scanf("%d%d%lld", &l, &r, &x);
  131. if(seg.query(, , n, l, r, x)) printf("YES\n");
  132. else printf("NO\n");
  133. }
  134. return ;
  135. }

2019牛客多校第四场B xor——线段树&&线性基的交的更多相关文章

  1. 2019牛客多校第四场B xor(线性基求交)题解

    题意: 传送门 给\(n\)个集合,每个集合有一些数.给出\(m\)个询问,再给出\(l\)和\(r\)和一个数\(v\),问你任意的\(i \in[l,r]\)的集合,能不能找出子集异或为\(v\) ...

  2. 2019牛客多校第七场C-Governing sand(线段树+枚举)

    Governing sand 题目传送门 解题思路 枚举每一种高度作为最大高度,则需要的最小花费的钱是:砍掉所有比这个高度高的树的所有花费+砍掉比这个高度低的树里最便宜的m棵树的花费,m为高度低的里面 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. clog就用clog的后缀名

    /tmp/log/shuanggou.clog /tmp/log/shuanggou.log /tmp/log/shuanggou_success.log /tmp/log/shuanggou_err ...

  2. python 脚本bak文件还原mssql数据库

    # -*- coding=utf-8 -*- import pyodbc from datetime import datetime import pymssql import decimal cla ...

  3. 【C++札记】new和delete

    介绍 1.malloc,free和new,delete区别. a.malloc,free是C/C++的标准库函数.new,delete是c++的操作符. b.malloc申请的是内存,严格意义不是&q ...

  4. Python基础运算符(算数、比较、赋值、逻辑、成员)

    Python运算符有(算数运算符.比较运算符.赋值运算符.逻辑运算符.位运算符.成员运算符.身份运算符): 本程序包含算数.比较.赋值.逻辑.成员运算符. 1.运算符测试 #!/usr/bin/pyt ...

  5. ARTS

    ARTS的初衷 Algorithm.主要是为了编程训练和学习.每周至少做一个 leetcode 的算法题(先从Easy开始,然后再Medium,最后才Hard).进行编程训练,如果不训练你看再多的算法 ...

  6. python之文件读写操作笔记

    对不同类的文件操作,需要调用相关的库文件,一般情况下,可以选择建立:写文件函数和读文件函数.在写文件与读文件函数中 我们可以采用:with  open('文件名','w', encoding='utf ...

  7. Java Web-JSTL

    Java Web-JSTL 概念 Java Server Pages Tag Library:JSP标准标签库 是由Apache组织提供的开源.免费JSP标签 用于简化和替换JSP页面上的Java代码 ...

  8. restTemplate源码解析(四)执行ClientHttpRequest请求对象

    所有文章 https://www.cnblogs.com/lay2017/p/11740855.html 正文 上一篇文章中,我们创建了一个ClientHttpRequest的实例.本文将继续阅读Cl ...

  9. vue基本语法概要(一)

    先看两种代码,再进行讲解 第一种格式: <template > <div> <div v-for=" item in sites "> < ...

  10. MySQL读写分离高可用集群及读操作负载均衡(Centos7)

    目录 概述 keepalived和heartbeat对比 一.环境 二.部署 部署lvs代理和keepalived MySQL+heartbeat+drbd的部署 MySQL主从复制 web服务器及a ...