[CCPC2022 广东] XOR Sum
数位 dp
看到这样求和价值的计算,考虑可不可以交换求和符号或者改变计算方式。
这题中的位运算使我们考虑按位计算贡献,价值可以写成:
其中
题目第二个要求即
设
转移看
如果是
如果是
记忆化搜索即可。
分析当前位上余数最多是多少,如果余数
复杂度
#include <bits/stdc++.h>
#define pii std::pair<int, int>
#define mk std::make_pair
#define fi first
#define se second
#define pb push_back
using i64 = long long;
using ull = unsigned long long;
const i64 iinf = 0x3f3f3f3f, linf = 0x3f3f3f3f3f3f3f3f;
const int N = 50, M = 170, K = 19, mod = 1e9 + 7;
i64 n, m, k;
i64 f[N][M][K], a[N], c[K][K];
i64 dfs(int dep, int left, int cnt) {
if(left >= 162) return 0;
if(dep == -1) return left == 0;
if(f[dep][left][cnt] != -1) return f[dep][left][cnt];
int dig = (!dep ? 0 : ((n >> (dep - 1)) & 1));
i64 ans = 0;
if(!a[dep]) {
for(int i = 0; i <= k - cnt; i++) {
int cur = left - 1LL * i * (k - i);
if(cur < 0) continue;
ans = (ans + c[k - cnt][i] * dfs(dep - 1, (cur << 1) | dig, cnt) % mod) % mod;
}
} else {
for(int i = 0; i <= cnt; i++) {
for(int j = 0; j <= k - cnt; j++) {
int cur = left - 1LL * (i + j) * (k - j - i);
if(cur < 0) continue;
ans = (ans + c[cnt][i] * c[k - cnt][j] % mod * dfs(dep - 1, (cur << 1) | dig, i) % mod) % mod;
}
}
}
f[dep][left][cnt] = ans;
return ans;
}
int solve() {
if(k == 1) return !n;
if(!m) return !n;
memset(f, -1, sizeof(f));
i64 l = 0, left = 0;
while(m) {
a[l++] = m % 2;
m >>= 1;
}
for(int i = l; i <= 50; i++) {
if((n >> i) & 1) {
left += (1LL << (i - l));
}
}
if(left >= 162) return 0;
return dfs(l, left, k);
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n >> m >> k;
c[0][0] = 1;
for(int i = 1; i <= k; i++) {
c[i][0] = 1;
for(int j = 1; j <= i; j++) {
c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
}
}
std::cout << solve() << "\n";
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析