Solved:3

Rank:331

B xor

题意:5e4个集合 每个集合最多32个数

   5e4个询问 询问l到r个集合是不是都有一个子集的xor和等于x

题解:在牛客多校第一场学了线性基 然后这个题就是求线性基的交 如果一个区间都能表示x 那么就表示这个区间内所有线性基的交能表示x

   用线段树维护这个东西 然后线性基交是抄的板子

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4.  
  5. int n, m;
  6. ll a[50005][35];
  7. struct node {
  8. ll val[35];
  9. };
  10.  
  11. node lb[200005], t1, t2;
  12. node merge(node A, node B) {
  13. node res;
  14. for(int i = 0; i <= 31; i++) t1.val[i] = t2.val[i] = A.val[i], res.val[i] = 0;
  15. for(int i = 0; i <= 31; i++) {
  16. ll x = B.val[i], t = 0;
  17. if(!x) continue;
  18.  
  19. int j = i;
  20. for(; j >= 0; j--) {
  21. if(x & (1LL << j)) {
  22. if(t1.val[j]) x ^= t1.val[j], t ^= t2.val[j];
  23. else break;
  24. }
  25. }
  26. if(!x) res.val[i] = t;
  27. else t1.val[j] = x, t2.val[j] = t;
  28. }
  29. return res;
  30. }
  31.  
  32. void build(int l, int r, int rt) {
  33. for(int i = 0; i <= 31; i++) lb[rt].val[i] = 0;
  34. if(l == r) {
  35. for(int i = 1; i <= a[l][0]; i++) {
  36. ll tmp = a[l][i];
  37. for(int j = 31; j >= 0; j--) {
  38. if(tmp & (1LL << j)) {
  39. if(!lb[rt].val[j]) {
  40. lb[rt].val[j] = tmp;
  41. break;
  42. }
  43. tmp ^= lb[rt].val[j];
  44. }
  45. }
  46. }
  47. return;
  48. }
  49.  
  50. int mid = l + r >> 1;
  51. build(l, mid, rt << 1);
  52. build(mid + 1, r, rt << 1 | 1);
  53. lb[rt] = merge(lb[rt << 1], lb[rt << 1 | 1]);
  54. }
  55.  
  56. bool ask(int rt, ll va) {
  57. for(int i = 31; i >= 0; i--) {
  58. if(va & (1LL << i)) va ^= lb[rt].val[i];
  59. }
  60. return va == 0;
  61. }
  62.  
  63. bool query(int ql, int qr, ll val, int l, int r, int rt) {
  64. if(ql <= l && qr >= r) return ask(rt, val);
  65.  
  66. bool res = 1;
  67. int mid = l + r >> 1;
  68. if(ql <= mid) res &= query(ql, qr, val, l, mid, rt << 1);
  69. if(qr > mid) res &= query(ql, qr, val, mid + 1, r, rt << 1 | 1);
  70. return res;
  71. }
  72.  
  73. int main() {
  74. scanf("%d%d", &n, &m);
  75. for(int i = 1; i <= n; i++) {
  76. scanf("%lld", &a[i][0]);
  77. for(int j = 1; j <= a[i][0]; j++) scanf("%lld", &a[i][j]);
  78. }
  79. build(1, n, 1);
  80. for(int i = 1; i <= m; i++) {
  81. int a, b; ll c;
  82. scanf("%d%d%lld", &a, &b, &c);
  83. if(query(a, b, c, 1, n, 1)) puts("YES");
  84. else puts("NO");
  85. }
  86. return 0;
  87. }

B xor

C sequence

题意:给定a,b两个数组 求所有l,r中 最大的 a的最小值*b的区间和

题解:存一下每个点作为最小值 左右两边的最大最小连续子序列

   比如每个点左边的最大连续子序列可以由在他左边的点转移过来 这个转移是具有单调性的

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int MAXN = 3e6 + 5;
  5.  
  6. int n;
  7. int a[MAXN];
  8. int b[MAXN];
  9. ll sum[MAXN];
  10. ll lz[MAXN], rz[MAXN], lf[MAXN], rf[MAXN];
  11. int lpos[MAXN], rpos[MAXN];
  12.  
  13. int main() {
  14. scanf("%d", &n);
  15. for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
  16. for(int i = 1; i <= n; i++) scanf("%d", &b[i]), sum[i] = sum[i - 1] + 1LL * b[i];
  17.  
  18. ll ans = 1LL * a[1] * b[1];
  19. lpos[1] = 0; lz[1] = lf[1] = 0;
  20. for(int i = 2; i <= n; i++) {
  21. int pos = i - 1;
  22. lz[i] = lf[i] = 0;
  23. while(pos >= 1 && a[i] <= a[pos]) {
  24. lz[i] = max(lz[i], lz[pos] + sum[i - 1] - sum[pos - 1]);
  25. lf[i] = min(lf[i], lf[pos] + sum[i - 1] - sum[pos - 1]);
  26. pos = lpos[pos];
  27. }
  28. lpos[i] = pos;
  29. }
  30.  
  31. rpos[n] = n + 1; rz[n] = rf[n] = 0;
  32. for(int i = n - 1; i >= 1; i--) {
  33. int pos = i + 1;
  34. rz[i] = rf[i] = 0;
  35. while(pos <= n && a[i] <= a[pos]) {
  36. rz[i] = max(rz[i], rz[pos] + sum[pos] - sum[i]);
  37. rf[i] = min(rf[i], rf[pos] + sum[pos] - sum[i]);
  38. pos = rpos[pos];
  39. }
  40. rpos[i] = pos;
  41. }
  42.  
  43. for(int i = 1; i <= n; i++) {
  44. if(a[i] > 0) {
  45. ans = max(ans, (lz[i] + rz[i] + 1LL * b[i]) * a[i]);
  46. } else ans = max(ans, (lf[i] + rf[i] + 1LL * b[i]) * a[i]);
  47. }
  48. printf("%lld\n", ans);
  49. return 0;
  50. }

C sequence

D triples I

题意:把一个数最少表示成几个数的 or和

题解:如果这个数不是三的倍数的话 那么最多用两个数也可以构造出来了 题目保证有解

   然后二进制下瞎逼搞搞 在算第i位大小时1没开LL wa死

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4.  
  5. ll val1[70];
  6. ll val2[70];
  7. int main() {
  8. int T;
  9. scanf("%d", &T);
  10. while(T--) {
  11. ll n; scanf("%lld", &n);
  12. int cnt1 = 0, cnt2 = 0;
  13. for(ll i = 0; i <= 60; i++) {
  14. if((n & (1LL << i)) == (1LL << i)) {
  15. if((1LL << i) % 3 == 1LL) val1[++cnt1] = (1LL << i);
  16. else val2[++cnt2] = (1LL << i);
  17. }
  18. }
  19. if(n % 3 == 0) printf("1 %lld\n", n);
  20. else if(n % 3 == 1) {
  21. if(cnt1 && cnt2) printf("2 %lld %lld\n", n - val1[1], val1[1] + val2[1]);
  22. else if(cnt1) printf("2 %lld %lld\n", n - val1[1], n - val1[2]);
  23. else if(cnt2) printf("2 %lld %lld\n", n - val2[1] - val2[2], val2[1] + val2[2] + val2[3]);
  24. } else {
  25. if(cnt1 && cnt2) printf("2 %lld %lld\n", n - val2[1], val1[1] + val2[1]);
  26. else if(cnt2) printf("2 %lld %lld\n", n - val2[1], n - val2[2]);
  27. else if(cnt1) printf("2 %lld %lld\n", n - val1[1] - val1[2], val1[1] + val1[2] + val1[3]);
  28. }
  29. }
  30. return 0;
  31. }

D triples I

E triples II (DP)

题意:给一个数a 求用n个是三的倍数的数把它与出来的方案数

题解:根本想不出来是DP.... 一个数的二进制有的位(单看这一位)是%3=1的 有的是%3=2的

   这里引用一个题解子集的定义:如果a中为1的二进制位在b中也都为1,我们称a是b的'子集'

   dp[i][j]表示有i个%3=1 j个%3=2的数的 且是三的倍数的子集数量 这个东西是可以预处理来的

   然后统计答案的时候 因为算的是子集 所以里面有不合法的子集.. 要把不合法的容斥搞出去

   以后多复习几遍....

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const ll mod = 998244353;
  5.  
  6. ll pow_mod(ll x, ll y) {
  7. ll res = 1;
  8. while(y) {
  9. if(y & 1) res = res * x % mod;
  10. x = x * x % mod;
  11. y >>= 1;
  12. }
  13. return res;
  14. }
  15.  
  16. ll dp[40][40];
  17. ll c[40][40];
  18.  
  19. int main() {
  20. c[0][0] = 1;
  21. for(int i = 1; i <= 35; i++) {
  22. c[i][0] = 1;
  23. for(int j = 1; j <= i; j++) c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
  24. }
  25.  
  26. for(int i = 0; i <= 35; i++) {
  27. for(int j = 0; j <= 35; j++) {
  28. for(int x = 0; x <= i; x++) {
  29. for(int y = 0; y <= j; y++) {
  30. if((x + y * 2) % 3 == 0) dp[i][j] = (dp[i][j] + c[i][x] * c[j][y] % mod) % mod;
  31. }
  32. }
  33. }
  34. }
  35.  
  36. int T;
  37. scanf("%d", &T);
  38. while(T--) {
  39. int cnt1 = 0, cnt2 = 0;
  40. ll n, a;
  41. scanf("%lld %lld", &n, &a);
  42. for(int i = 0; i <= 61; i++) {
  43. if(a & (1LL << i)) {
  44. if(i & 1) cnt2++;
  45. else cnt1++;
  46. }
  47. }
  48.  
  49. ll ans = 0;
  50. for(int i = cnt1 + cnt2; i >= 0; i--) {
  51. ll tmp = 0;
  52. for(int j = 0; j <= cnt1; j++) {
  53. if(i - j > cnt2 || i < j) continue;
  54. tmp += c[cnt1][j] * c[cnt2][i - j] % mod * pow_mod(dp[j][i - j], n) % mod;
  55. tmp %= mod;
  56. }
  57. if((cnt1 + cnt2 - i) & 1) tmp = -tmp;
  58. ans = (ans + tmp + mod) % mod;
  59. }
  60. printf("%lld\n", ans);
  61. }
  62. return 0;
  63. }

E triples II

2019牛客多校 Round4的更多相关文章

  1. 2019牛客多校第一场 I Points Division(动态规划+线段树)

    2019牛客多校第一场 I Points Division(动态规划+线段树) 传送门:https://ac.nowcoder.com/acm/contest/881/I 题意: 给你n个点,每个点有 ...

  2. 2019牛客多校第二场 A Eddy Walker(概率推公式)

    2019牛客多校第二场 A Eddy Walker(概率推公式) 传送门:https://ac.nowcoder.com/acm/contest/882/A 题意: 给你一个长度为n的环,标号从0~n ...

  3. 2019牛客多校第八场 F题 Flowers 计算几何+线段树

    2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...

  4. 2019牛客多校第一场E ABBA(DP)题解

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

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

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

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

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

  7. [2019牛客多校第二场][G. Polygons]

    题目链接:https://ac.nowcoder.com/acm/contest/882/G 题目大意:有\(n\)条直线将平面分成若干个区域,要求处理\(m\)次询问:求第\(q\)大的区域面积.保 ...

  8. 2019 牛客多校第一场 D Parity of Tuples

    题目链接:https://ac.nowcoder.com/acm/contest/881/D 看此博客之前请先参阅吕凯飞的论文<集合幂级数的性质与应用及其快速算法>,论文中很多符号会被本文 ...

  9. 2019牛客多校第二场D-Kth Minimum Clique

    Kth Minimum Clique 题目传送门 解题思路 我们可以从没有点开始,把点一个一个放进去,先把放入一个点的情况都存进按照权值排序的优先队列,每次在新出队的集合里增加一个新的点,为了避免重复 ...

随机推荐

  1. #2020征文-开发板# 用鸿蒙开发AI应用(五)HDF 驱动补光灯

    目录: 前言 硬件准备 HDF 驱动开发 总结 前言上一篇,我们在鸿蒙上运行了第一个程序,这一篇我们来编写一个驱动开启摄像头的红外补光灯,顺便熟悉一下鸿蒙上的 HDF 驱动开发. 硬件准备先查一下原理 ...

  2. 在Linux系统下限制指定目录的大小以及文件/文件夹数量

    背景说明 在Linux操作系统下有时需要限制一个指定文件夹的大小和文件夹内可存储的文件数量,有可能是出于安全的考量或者定制化的配置,这里我们提供了一种方案:用dd创建一个空的img镜像,进行格式化的配 ...

  3. HashMap为什么效率高?来看看这个小demo

    一.前情回顾:在程序中有时候需要存放对象,容器应运而生.容器分为集合和Map.集合在这里不说,说说Map.Map在英语中是地图的意思,这个名字真是起的好,可以让人顾名思义.Map,就是存放键值对的结构 ...

  4. 【Linux】fio测试读写速度

    需要安装fio yum install fio -y 有很多依赖包     FIO用法: 随机读:(可直接用,向磁盘写一个2G文件,10线程,随机读1分钟,给出结果) fio -filename=/h ...

  5. 文件监控性能问题【BUG】

    文件监控性能问题[BUG] 背景:JAVA写了一个文件夹目录监控的程序,使用的是org.apache.commons.io.monitor 包,项目稳定运行了一个月,现场反馈,文件夹数据处理越来越慢, ...

  6. 开篇:免费开源的趣讲 ZooKeeper 教程(连载)

    本文作者:HelloGitHub-老荀 一.起因 良好的开端,是成功的一半. 我是作者老荀,一个普通的程序员,没有 985 和 211 的背景,也从没在大厂工作过.仅仅是喜欢研究技术,一直想做一个讲解 ...

  7. 指针锁定 Pointer Lock API 用法

    指针锁定 Pointer Lock API 通过它可以访问原始的鼠标运动(基于指针的相对位移 movementX / movementY),把鼠标事件的目标锁定到一个特定的元素,同时隐藏视图中的指针光 ...

  8. Databricks 第9篇:Spark SQL 基础(数据类型、NULL语义)

    Spark SQL 支持多种数据类型,并兼容Python.Scala等语言的数据类型. 一,Spark SQL支持的数据类型 整数系列: BYTE, TINYINT:表示1B的有符号整数 SHORT, ...

  9. python中json模块的使用

    Python自带json模块,它有loads.dumps.load和dump这4个功能,用于Json格式字符串和Python数据类型间进行转换. 一.json.loads() 把Json格式字符串解码 ...

  10. 忒修斯的Mac

    我有一台Mac笔记本,用了快6年了,当初买它的时候还借了几千块. 三年前,它的屏幕坏了,修理的方式就是直接换屏,而换屏其实就是上半部分连壳带屏幕整个换掉,简单的说:另一台电脑的上半身嫁接过来. 今年, ...