luogu P5539 【XR-3】Unknown Mother-Goose

https://www.luogu.com.cn/problem/P5539

想到了,但没有完全想到

先丢一个时间复杂度是\(O(\frac{n|S|}{w})\)
要手写\(bitset\)

\(|S|\)中的每个数的倍数都设为\(1\)
统计连续三个\(1\)的个数

具体实现看代码吧

code:

#include<bits/stdc++.h>
#define ull unsigned long long
#define lowbit(x) (x & -x)
using namespace std;
int count(ull x) {
    int ret = 0;
    while(x) ret ++, x -= lowbit(x);
    return ret;
}
const int N = 1000000000 / 63;
ull a[N << 1], b[71];
int n, m, gs;
void insert(int x) {
    if(x >= 64) for(int i = 0; i <= n; i += x) a[i >> 6] |= (1ull << (i & 63));
    else {
        for(int i = 0; i < 64; i ++) b[i] = 0;
        for(int i = 0; i < 64; i ++) b[(i * x) >> 6] |= (1ull << ((i * x) & 63));
        //for(int i = 0; i < 64; i ++) printf("%llu ", b[i]); printf("\n");
        for(int i = 0; i <= gs; i += x) {
            for(int j = 0; j < x; j ++) {
                a[i + j] |= b[j];
            }
        }
    }
}
void print(ull x) {
    for(int i = 0; i < 64; i ++) printf("%llu", (x >> i) & 1); printf("\n");
}
int main() {
    scanf("%d%d", &n, &m);
    gs = n >> 6;
    while(m --) {
        int x;
        scanf("%d", &x); insert(x);
        //break;
    }

    for(int i = (gs << 6), t = 0; i < ((gs + 1) << 6); i ++, t ++) if(((a[gs] >> t) & 1) && i > n) {
      //  printf("*%d  %d  ", i, t);
        a[gs] ^= (1ull << t);
    }
    if(a[0] & 1) a[0] ^= 1;
    int ans = 0;
    //for(int i = 0; i <= gs; i ++) print(a[i]);
    for(int i = 0; i <= gs; i ++) 
        ans += count(a[i] & ((a[i] << 1) | (a[i - 1] >> 63)) & ((a[i] << 2) | (a[i - 1] >> 62)));
    printf("%d", ans);
    return 0;
}
posted @ 2022-02-16 15:34  lahlah  阅读(117)  评论(0编辑  收藏  举报