F - Nim
F - Nim
Problem Statement
You are given integers . Find the number, modulo , of triples of positive integers that satisfy all of the following three conditions.
- for every .
- is a multiple of for every .
- , where denotes bitwise xor.
What is bitwise xor?
The bitwise xor of non-negative integers and , , is defined as follows.- When is written in binary, the s place () is if exactly one of the s places of and is , and otherwise.
Constraints
- All input values are integers.
Input
The Input is given from Standard Input in the following format:
Output
Print the answer.
Sample Input 1
13 2 3 5
Sample Output 1
4
Four triples satisfy the conditions: .
Sample Input 2
1000000000000000000 1 1 1
Sample Output 2
426724011
Sample Input 3
31415926535897932 3 8 4
Sample Output 3
759934997
解题思路
用刚学的递归写法来做这道数位 dp,请参考数位 dp 学习笔记(灵神模板)。
对 , 和 同时进行数位 dp,找的是满足条件的三元组的数量。很显然由于涉及到异或运算,需要把 看作是二进制数。考虑参数的选择,由于要满足 因此还需要用一个参数 来记录前 位所表示的二进制数模 的值。另外由于询问的区间是 ,所以不可以有前导零。最后在枚举 , 和 第 位选择的数 ,, 时,要保证 。
一些技巧,事实上并不需要把 转换成二进制字符串然后 dp,直接用 Xi >> u & 1
来得到 在二进制下第 位的值。由于 最大为 ,因此二进制位最多有 位,所以一开始传入的参数 为 ,从高位往低位递归,边界条件是 。
AC 代码如下,时间复杂度为 :
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 60, mod = 998244353;
LL n, a1, a2, a3;
int f[N][10][10][10][2][2][2][2][2][2];
int dfs(int u, int r1, int r2, int r3, int h1, int h2, int h3, int l1, int l2, int l3) {
if (u < 0) return !r1 && !r2 && !r3 && !l1 && !l2 && !l3;
if (f[u][r1][r2][r3][h1][h2][h3][l1][l2][l3] != -1) return f[u][r1][r2][r3][h1][h2][h3][l1][l2][l3];
int ret = 0;
int up1 = h1 ? n >> u & 1 : 1, up2 = h2 ? n >> u & 1 : 1, up3 = h3 ? n >> u & 1 : 1;
for (int x1 = 0; x1 <= up1; x1++) {
for (int x2 = 0; x2 <= up2; x2++) {
for (int x3 = 0; x3 <= up3; x3++) {
if (!(x1 ^ x2 ^ x3)) ret = (ret + dfs(u - 1, (r1 * 2 + x1) % a1, (r2 * 2 + x2) % a2, (r3 * 2 + x3) % a3, h1 && x1 == up1, h2 && x2 == up2, h3 && x3 == up3, l1 && !x1, l2 && !x2, l3 && !x3)) % mod;
}
}
}
return f[u][r1][r2][r3][h1][h2][h3][l1][l2][l3] = ret;
}
int main() {
scanf("%lld %lld %lld %lld", &n, &a1, &a2, &a3);
memset(f, -1, sizeof(f));
printf("%d", dfs(59, 0, 0, 0, 1, 1, 1, 1, 1, 1));
return 0;
}
参考资料
Editorial - GAMEFREAK Programming Contest 2023 (AtCoder Beginner Contest 317):https://atcoder.jp/contests/abc317/editorial/7047
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17991695
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2023-01-27 B. GCD Partition
2023-01-27 D. Fixed Prefix Permutations