如果cnt[ i ][ j ] 表示第 i 个集合数字 j 的奇偶性的话第三部操作很难处理。
所以我们考虑cnt[ i ][ j ] 表示第 i 个集合 j 的倍数的奇偶性, 第三部操作就想到与两个bitset取&操作。
然后考虑询问的时候还原回去, 就相当于&上一个莫比乌斯系数就可以了。
#include<bits/stdc++.h> using namespace std; const int N = 7001; using BS = bitset<N>; int n, q; BS fac[N]; BS mu[N]; BS b[100007]; BS ans; int miu[N]; int main() { for(int i = 1; i < N; i++) { for(int j = i; j < N; j += i) { fac[j][i] = 1; } } miu[1] = 1; for(int i = 1; i < N; i++) { for(int j = i + i; j < N; j += i) { miu[j] -= miu[i]; } } for(int i = 1; i < N; i++) { for(int j = 1; i * j < N; j++) { mu[i][i * j] = miu[j] ? 1 : 0; } } scanf("%d%d", &n, &q); while(q--) { int op, x, y, z, v; scanf("%d", &op); if(op == 1) { scanf("%d%d", &x, &v); b[x] = fac[v]; } else if(op == 2) { scanf("%d%d%d", &x, &y, &z); b[x] = b[y] ^ b[z]; } else if(op == 3) { scanf("%d%d%d", &x, &y, &z); b[x] = b[y] & b[z]; } else { scanf("%d%d", &x, &v); BS ans = b[x] & mu[v]; printf("%d", ans.count() % 2); } } puts(""); return 0; } /** **/