1 条题解
-
0
自动搬运
来自洛谷,原作者为

tuboshu666
**搬运于
2025-08-24 23:11:18,当前版本为作者最后更新于2025-03-31 20:57:26,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
思路
集合的并、交、取补集操作,容易想到使用
bitset优化。由于 的范围较小,可以用一个bitset来代表一个集合。定义:一个 位的bitset第 位为 时,代表数字 在该集合中。对于 的集合,直接暴力将 的倍数置 即可。
后 个集合,实际都是通过 个操作构造而来。
对于操作 :由或运算的性质:对应的二进制位有 个为 ,那么该位在操作后为 。将 和 进行或运算,得到的就是两个集合并后的结果。
对于操作 :由与运算的性质:对应的二进制位同时为 时,该位操作后才为 。于是将 和 进行与运算,就是集合交后的结果。
对于操作 :其实就是在全集 取 的补集。想到异或的性质。将 和 进行异或,那么两集合同时存在的数,该位会置 ,剩下的置 ,符合补集要求。
Code
#include <iostream> #include <bitset> #include <vector> using namespace std; const int N = 5e4 + 10; typedef bitset<N> bt; //n位的bitset模拟一个集合 int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n,m,q; cin >> n >> m >> q; vector<bt> a(n+m+1); for (int i = 1 ; i <= n ; i++) { for (int j = i ; j <= n ; j += i) { a[i][j] = 1; //1到n的集合初始化 } } for (int i = 1 ; i <= m ; i++) { int op; cin >> op; if (op == 1) { int x,y; cin >> x >> y; a[i+n] = a[x] | a[y]; //或运算模拟集合并 } else if (op == 2) { int x,y; cin >> x >> y; a[i+n] = a[x] & a[y]; //与运算模拟集合交 } else { int x; cin >> x; a[i+n] = a[1] ^ a[x]; //异或运算模拟取补集 } } for (int i = 1 ; i <= q ; i++) { int x,y; cin >> x >> y; if (a[x][y] == 1) cout << "TAK" << endl; else cout << "NIE" << endl; } return 0; }题外话
本篇并未详细介绍
bitset。如有需求,请移步扶苏的bitset浅谈。另外,推荐一道类似的题目:
- 1
信息
- ID
- 11667
- 时间
- 5000ms
- 内存
- 3907MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者