Solved:3

Rank:331

B xor

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

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

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

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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll; int n, m;
ll a[50005][35];
struct node {
ll val[35];
}; node lb[200005], t1, t2;
node merge(node A, node B) {
node res;
for(int i = 0; i <= 31; i++) t1.val[i] = t2.val[i] = A.val[i], res.val[i] = 0;
for(int i = 0; i <= 31; i++) {
ll x = B.val[i], t = 0;
if(!x) continue; int j = i;
for(; j >= 0; j--) {
if(x & (1LL << j)) {
if(t1.val[j]) x ^= t1.val[j], t ^= t2.val[j];
else break;
}
}
if(!x) res.val[i] = t;
else t1.val[j] = x, t2.val[j] = t;
}
return res;
} void build(int l, int r, int rt) {
for(int i = 0; i <= 31; i++) lb[rt].val[i] = 0;
if(l == r) {
for(int i = 1; i <= a[l][0]; i++) {
ll tmp = a[l][i];
for(int j = 31; j >= 0; j--) {
if(tmp & (1LL << j)) {
if(!lb[rt].val[j]) {
lb[rt].val[j] = tmp;
break;
}
tmp ^= lb[rt].val[j];
}
}
}
return;
} int mid = l + r >> 1;
build(l, mid, rt << 1);
build(mid + 1, r, rt << 1 | 1);
lb[rt] = merge(lb[rt << 1], lb[rt << 1 | 1]);
} bool ask(int rt, ll va) {
for(int i = 31; i >= 0; i--) {
if(va & (1LL << i)) va ^= lb[rt].val[i];
}
return va == 0;
} bool query(int ql, int qr, ll val, int l, int r, int rt) {
if(ql <= l && qr >= r) return ask(rt, val); bool res = 1;
int mid = l + r >> 1;
if(ql <= mid) res &= query(ql, qr, val, l, mid, rt << 1);
if(qr > mid) res &= query(ql, qr, val, mid + 1, r, rt << 1 | 1);
return res;
} int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) {
scanf("%lld", &a[i][0]);
for(int j = 1; j <= a[i][0]; j++) scanf("%lld", &a[i][j]);
}
build(1, n, 1);
for(int i = 1; i <= m; i++) {
int a, b; ll c;
scanf("%d%d%lld", &a, &b, &c);
if(query(a, b, c, 1, n, 1)) puts("YES");
else puts("NO");
}
return 0;
}

B xor

C sequence

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

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

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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 3e6 + 5; int n;
int a[MAXN];
int b[MAXN];
ll sum[MAXN];
ll lz[MAXN], rz[MAXN], lf[MAXN], rf[MAXN];
int lpos[MAXN], rpos[MAXN]; int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i++) scanf("%d", &b[i]), sum[i] = sum[i - 1] + 1LL * b[i]; ll ans = 1LL * a[1] * b[1];
lpos[1] = 0; lz[1] = lf[1] = 0;
for(int i = 2; i <= n; i++) {
int pos = i - 1;
lz[i] = lf[i] = 0;
while(pos >= 1 && a[i] <= a[pos]) {
lz[i] = max(lz[i], lz[pos] + sum[i - 1] - sum[pos - 1]);
lf[i] = min(lf[i], lf[pos] + sum[i - 1] - sum[pos - 1]);
pos = lpos[pos];
}
lpos[i] = pos;
} rpos[n] = n + 1; rz[n] = rf[n] = 0;
for(int i = n - 1; i >= 1; i--) {
int pos = i + 1;
rz[i] = rf[i] = 0;
while(pos <= n && a[i] <= a[pos]) {
rz[i] = max(rz[i], rz[pos] + sum[pos] - sum[i]);
rf[i] = min(rf[i], rf[pos] + sum[pos] - sum[i]);
pos = rpos[pos];
}
rpos[i] = pos;
} for(int i = 1; i <= n; i++) {
if(a[i] > 0) {
ans = max(ans, (lz[i] + rz[i] + 1LL * b[i]) * a[i]);
} else ans = max(ans, (lf[i] + rf[i] + 1LL * b[i]) * a[i]);
}
printf("%lld\n", ans);
return 0;
}

C sequence

D triples I

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

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

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

#include <bits/stdc++.h>
using namespace std;
typedef long long ll; ll val1[70];
ll val2[70];
int main() {
int T;
scanf("%d", &T);
while(T--) {
ll n; scanf("%lld", &n);
int cnt1 = 0, cnt2 = 0;
for(ll i = 0; i <= 60; i++) {
if((n & (1LL << i)) == (1LL << i)) {
if((1LL << i) % 3 == 1LL) val1[++cnt1] = (1LL << i);
else val2[++cnt2] = (1LL << i);
}
}
if(n % 3 == 0) printf("1 %lld\n", n);
else if(n % 3 == 1) {
if(cnt1 && cnt2) printf("2 %lld %lld\n", n - val1[1], val1[1] + val2[1]);
else if(cnt1) printf("2 %lld %lld\n", n - val1[1], n - val1[2]);
else if(cnt2) printf("2 %lld %lld\n", n - val2[1] - val2[2], val2[1] + val2[2] + val2[3]);
} else {
if(cnt1 && cnt2) printf("2 %lld %lld\n", n - val2[1], val1[1] + val2[1]);
else if(cnt2) printf("2 %lld %lld\n", n - val2[1], n - val2[2]);
else if(cnt1) printf("2 %lld %lld\n", n - val1[1] - val1[2], val1[1] + val1[2] + val1[3]);
}
}
return 0;
}

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的数的 且是三的倍数的子集数量 这个东西是可以预处理来的

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

   以后多复习几遍....

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353; ll pow_mod(ll x, ll y) {
ll res = 1;
while(y) {
if(y & 1) res = res * x % mod;
x = x * x % mod;
y >>= 1;
}
return res;
} ll dp[40][40];
ll c[40][40]; int main() {
c[0][0] = 1;
for(int i = 1; i <= 35; i++) {
c[i][0] = 1;
for(int j = 1; j <= i; j++) c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
} for(int i = 0; i <= 35; i++) {
for(int j = 0; j <= 35; j++) {
for(int x = 0; x <= i; x++) {
for(int y = 0; y <= j; y++) {
if((x + y * 2) % 3 == 0) dp[i][j] = (dp[i][j] + c[i][x] * c[j][y] % mod) % mod;
}
}
}
} int T;
scanf("%d", &T);
while(T--) {
int cnt1 = 0, cnt2 = 0;
ll n, a;
scanf("%lld %lld", &n, &a);
for(int i = 0; i <= 61; i++) {
if(a & (1LL << i)) {
if(i & 1) cnt2++;
else cnt1++;
}
} ll ans = 0;
for(int i = cnt1 + cnt2; i >= 0; i--) {
ll tmp = 0;
for(int j = 0; j <= cnt1; j++) {
if(i - j > cnt2 || i < j) continue;
tmp += c[cnt1][j] * c[cnt2][i - j] % mod * pow_mod(dp[j][i - j], n) % mod;
tmp %= mod;
}
if((cnt1 + cnt2 - i) & 1) tmp = -tmp;
ans = (ans + tmp + mod) % mod;
}
printf("%lld\n", ans);
}
return 0;
}

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. P3714 [BJOI2017]树的难题 点分治+线段树合并

    题目描述 题目传送门 分析 路径问题考虑点分治 对于一个分治中心,我们可以很容易地得到从它开始的一条路径的价值和长度 问题就是如何将不同的路径合并 很显然,对于同一个子树中的所有路径,它们起始的颜色是 ...

  2. laravel5.4 接入qq第三方登录

    第一步:先composer安装需要用到的依赖,命令行如下 composer require socialiteproviders/qq 第二步:在config/app.php 中的 providers ...

  3. Zap简单使用

    前言 zap 是 uber 开源的一个日志记录的包, uber 在 go 的领域建树颇多, zap 更是优秀, 相比于自带的 log ,他有更多的功能, 当然, 最显眼的还是他很快, 本文介绍 zap ...

  4. 记一次Goroutine与wg导致的问题

    前言 今天发现了一个问题是之前一直没有注意到的,这里记一下 正文 Send Closed Chan 问题概述 代码逻辑是启动时启动多个 channel, channel1 获取数据监听数据处理后发送给 ...

  5. 一文带你学会AQS和并发工具类的关系

    1. 存在的意义   AQS(AbstractQueuedSynchronizer)是JAVA中众多锁以及并发工具的基础,其底层采用乐观锁,大量使用了CAS操作, 并且在冲突时,采用自旋方式重试,以实 ...

  6. FAT32、NTFS、exFAT有什么区别?

    文件系统 我们经常会对电脑硬盘.U盘.移动硬盘进行格式化,而在格式化硬盘的时候会弹出文件系统的选项,分别有FAT32.NTFS.exFAT三种格式,那么FAT32.NTFS.exFAT有什么区别? 在 ...

  7. 那些最全面的Windows10安装pytorch踩过的坑以及如何应用

    那些最全面的Windows10安装pytorch踩过的坑以及如何应用 一.pytorch简介 2017年1月,由Facebook人工智能研究院(FAIR)基于Torch推出了PyTorch.它是一个基 ...

  8. innodb日志文件大小

    innodb是用多个文件作为一组循环日志,通常不需要修改默认的日志数量,只修改每个日志文件的大小即可,要修改日志文件大小,需要完全关闭mysql,将旧的日志文件移到其他地方保存,重新配置参数,然后重启 ...

  9. CTFHub - Web(五)

    eval执行: 1.进入网页,显示源码, <?php if (isset($_REQUEST['cmd'])) { eval($_REQUEST["cmd"]); } els ...

  10. 【JAVA并发第三篇】线程间通信

    线程间的通信 JVM在运行时会将自己管理的内存区域,划分为不同的数据区,称为运行时数据区.每个线程都有自己私有的内存空间,如下图示: Java线程按照自己虚拟机栈中的方法代码一步一步的执行下去,在这一 ...