Codeforces Round 871 H๋ฒˆ
ย - Last update: 2023-05-10

๋ญ”๊ฐ€ ๋ฐœ์ƒ์ด ์ž˜ ์•ˆ๋– ์˜ค๋ฅธ๋‹ค ์‹ถ์œผ๋ฉด DP์ธ๋“ฏ. ์‹œํ—˜ ๋๋‚˜๊ณ  ๋ฐ˜์‘์„ ๋ณด๋‹ˆ ์ฝ”ํฌ DP ๋Œ€ํ‘œ์œ ํ˜•(?) ์ทจ๊ธ‰์ด๋‹ค. ์ต์ˆ™ํ•ด์งˆ ํ•„์š”๊ฐ€ ์žˆ๋Š”๋“ฏ. 10^9 + 7 ๋”ฐ์œ„์™€ ๊ฐ™์€ ์ˆ˜๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ๋„ DP ์‹ ํ˜ธ ์ค‘ ํ•˜๋‚˜. DP๋Š” ๊พธ์ค€ํ•œ ์—ฐ์Šต๋งŒ์ด ์‚ด ๊ธธ.

๋ฌธ์ œ๋Š” ์›์†Œ๋ผ๋ฆฌ AND operation์„ ํ•œ ๋’ค k๊ฐœ์˜ ๋น„ํŠธ๊ฐ€ ์ผœ์ ธ์žˆ๋Š” ์žˆ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ์„ธ๋Š” ๊ฒƒ.

N * 64 ๋งŒํผ์˜ DP ๋ฐฐ์—ด์„ ๋งŒ๋“ค๊ณ , ์•„๋ž˜์™€ ๊ฐ™์€ ์„ธ case๋ฅผ ๋น ๋œจ๋ฆฌ์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.

// i๋ฒˆ์งธ๋ฅผ ์ฑ„์šฐ๋Š” ์ƒํ™ฉ
// ๊ธฐ๋ณธ๊ฐ’ ์„ธํŒ…
DP[i][A[i]] = 1;
// i๋ฒˆ์งธ ์›์†Œ๋ฅผ ์„ ํƒํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋Š” i-1๋ฒˆ์งธ์˜ ๊ฒฝ์šฐ์˜ ์ˆ˜์™€ ๊ฐ™๋‹ค.
DP[i][j] += DP[i-1][j];
// i๋ฒˆ์งธ ์›์†Œ๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒฝ์šฐ ๊ฐ’์€ ํƒ€๊ฒŸ ๊ฐ’์ด j & A[i]๋กœ ๋ณ€๊ฒฝ๋œ๋‹ค.
DP[i][j & A[i]] += DP[i-1][j];

๊ทธ๋ฆฌ๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•  ๋•Œ๋Š” DP[N][j]๋ฅผ ๋ณด๋˜, j๋Š” popcnt ๊ฐ€ K๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ๋งŒ accept ํ•œ๋‹ค.

Solution

int N, K;
int A[200'001];
ll DP[200'001][64];
ll MOD = 1'000'000'007;
void solve() {
scanf("%d %d", &N, &K);
_D("N: %d, K: %d\n", N, K);
for(R int i = 1; i <= N; ++i) {
scanf("%d", &A[i]);
for(R int j = 0; j < 64; ++j) {
DP[i][j] = 0;
}
}
for(R int i = 1; i <= N; ++i) {
DP[i][A[i]] += 1;
for(int j = 0; j < 64; ++j) { // prev value
DP[i][j] += DP[i-1][j]; // ์ƒˆ๋กœ์šด ๊ฐ’์„ ์“ฐ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ
DP[i][j] %= MOD;
int nv = j & A[i];
DP[i][nv] += DP[i-1][j];
DP[i][nv] %= MOD;
}
}
ll ans = 0;
for(int j = 0; j < 64; ++j) {
if (cntbit(j) == K) {
ans += DP[N][j];
ans %= MOD;
_D("DP[%d][%d] = %d\n", N, j, DP[N][j]);
}
}
printf("%lld\n", ans);
}
๐Ÿท๏ธ ์ฃผ์ œ ๋ชฉ๋ก: