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;
}
题意:定义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;
}
相关文章推荐
- Java的加载资源文件+JavaBean+内省机制
- UVa 1589 Xiangqi
- Windows 下基于 Eclipse 的可视化远程 Linux 开发环境搭建
- Linux内核如何装载和启动一个可执行程序
- iOS开发之 用第三方类库实现ScrollView
- raspberry pi使用vsftpd搭建ftp服务器
- 设计模式-4-装饰者模式
- 设计模式-3-工厂方法和抽象工厂模式
- 【Asp.net】初识
- 2016.4.10 线段树练习
- 20145120 《Java程序设计》第6周学习总结
- Atitit.跨语言异常转换机制 java c# php到js的异常转换
- [整理+原创]ubuntu Thunderbird Mail设置自动提醒
- Atitit.跨语言异常转换机制 java c# php到js的异常转换
- 组合数学 随记
- su和sudo命令
- 剑指Offer--008-旋转数组的最小数字
- jQuery点击按钮实现div的隐藏和显示切换效果
- 输出1-100之间的奇数
- struts2环境配置