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