Codeforces 1097F Alex and a TV Show bitset + 莫比乌斯反演

Alex and a TV Show

如果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;
}

/**
**/

 

posted @ 2019-11-05 15:30  NotNight  阅读(129)  评论(0编辑  收藏  举报