您的位置:首页 > 其它

hihocoder 1259 (数位DP)

2016-04-10 21:38 267 查看
连接:点击打开链接

题意:定义g(x)为f(1)到f(n)中模k余n的个数,求出所有g(x)的异或和.

坑爹UVA一直报RE然后转向hihocoder就过了~

f(2x)=3f(x),f(2x+1)=f(2x)+1.

然后发现f(1)到f(n)在三进制下等价于二进制下的1到n,然后就可以用数位DP搞了.

这个思想下的转移方程dp(d,m) = dp(d-1, (m-x)%k).

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

long long dp[68][68686];
long long n, ans[68686];
int mod;
int bit[68], l;
#define pow Pow
long long pow[68];

void solve (long long num) {
long long cur = 1;
l = 0;
while (num) {
bit[++l] = (num&1);
num >>= 1;
}
pow[0] = 1;
for (int i = 1; i <= l; i++) pow[i] = pow[i-1]*3%mod;
for (int i = 1; i <= l; i++, cur *= 3, cur %= mod) {
for (int j = 0; j < mod; j++) {
dp[i][(j+cur)%mod] += dp[i-1][j];//1
dp[i][j] += dp[i-1][j];//0
}
}
memset (ans, 0, sizeof ans);
cur = 0;
for (int i = l; i >= 1; i--) {
if (bit[i]) {
for (int j = 0; j < mod; j++) {
ans[(j+cur)%mod] += dp[i-1][j];
}
cur += pow[i-1]%mod;
cur %= mod;
}
}
ans[cur]++;//最终的数字
ans[0]--;//排除数字0
long long gg = 0;
for (int i = 0; i < mod; i++) {
gg ^= ans[i];
}
cout << gg << endl;
return ;
}

int main () {
//freopen ("in.txt", "r", stdin);
int t;
scanf ("%d", &t);
while (t--) {
memset (dp, 0, sizeof dp);
dp[0][0] = 1;
scanf ("%lld%d", &n, &mod);
solve (n);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: