Codeforces Round #772 (Div. 2) D - Infinite Set

f[p - i]代表原二进制串左移i个单位能得到的不同二进制串的个数
考虑去重,如果a[i]是否能回溯到a[j],那么就无需考虑,从S中舍去
最后对于S中的每一个数,bit为这个数在二进制下的最高位,f[min(p, bit)]即为这个数对答案的贡献

f[i]的另一种更好理解的表示

#include<bits/stdc++.h>
using namespace std;

#define fr first
#define se second
#define et0 exit(0);
#define rep(i, a, b) for(int i = (a); i <= (b); i ++)
#define rrep(i, a, b) for(int i = (a); i >= (b); i --)

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef unsigned long long ULL;

const int INF = 0X3f3f3f3f, N = 2e5 + 10, MOD = 1e9 + 7;
const double eps = 1e-7;

int a[N];
LL f[N];

unordered_set<int> S;

void work() {
	int n, p;
	cin >> n >> p;
	rep(i, 1, n) cin >> a[i];
	rep(i, 1, n) S.insert(a[i]);

	f[p] = 0, f[p - 1] = 1;
	rrep(i, p - 2, 0) f[i] = (f[i + 1] + f[i + 2] + 1) % MOD;

	rep(i, 1, n) {
		int x = a[i];
		while (x) {
			if (x & 1) x >>= 1;
			else if (x % 4 == 0) x /= 4;
			else break;
			if (S.count(x)) {
				S.erase(a[i]);
				break;
			}
		}
	}

	LL res = 0;
	rep(i, 1, n) {
		int bit = log2(a[i]);
		if (S.count(a[i])) res = (res + f[min(p, bit)]) % MOD;
	}

	cout << res << endl;
}

signed main() {

	work();

	return 0;
}
posted @ 2022-07-04 18:19  xhy666  阅读(36)  评论(0)    收藏  举报