-
[E] New Year 2014
- 时间限制: 2000 ms 内存限制: 262144 K
- 问题描述
-
In the New Year 2014, Xiao Ming is thinking about the question: give two integers N and K, Calculate the number of the numbers of satisfy the following conditions:
1. It is a positive integer and is not greater than N.
2. Xor value of its all digital is K.
For example N = 12, K = 3, the number of satisfy condition is 3 and 12 (3 = 3, 1 ^ 2 = 3).
In order to let Xiao Ming happy in the New Year 2014, can you help him?
- 输入
-
There are multiple test cases, each test sample contains two positive integers N and K (0 <= N, K < 10 ^ 18), End to file.
- 输出
-
For each case, output the number of the numbers of satisfy condition in one line.
- 样例输入
-
12 3 999 5 12354 8
- 样例输出
-
2 76 662
- 提示
-
无
- 来源
-
宁静致远 @HBMY
- 操作
很久没做题了,对于这种最简单的数位dp都做不了!
题意:求1~n的数中符合每一数位的异或为k的个数。
题解:最简单的数位dp,不过要懂得a = b1^b2^……bm 推出 a^b1^b2……bm = 0;
所以我们dfs时dp[i][j]代表着选择了i位和前i位异或值为j的个数(剩下的全排列所有情况)。
然后就一步步递归下去。。
不过这些都是包括零,所以还要减去0.。
#include<cstdio>
#include<cstring>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<iostream>
#include<cstdlib>
using namespace std;
int Max(int a,int b)
{
return a>b?a:b;
}
long long dp[25][20];
long long n,k;
int num[20];
int tran(long long n)
{
int i = 0;
while(n)
{
num[i++] = n%10;
n/=10;
}
return i;
}
long long DFSdp(int b,int s,int r,int doing)
{
if(b==0 )
{
if(r==0)
return 1;
else
return 0;
}
if(!doing && dp[b][r]!=-1)
{
return dp[b][r];
}
int end = doing==1?num[b-1]:9;
long long ans = 0;
for(int i=0;i<=end;i++)
{
ans += DFSdp(b-1,i,r^i,doing&&i==end);
}
if(!doing)
dp[b][r] = ans;
return ans;
}
int main()
{
memset(dp,-1,sizeof(dp));
while(~scanf("%lld%lld",&n,&k))
{
int b = tran(n);
if(k>15)
{
printf("0\n");
continue ;
}
long long ans = DFSdp(b,0,(int)k,1);
if(k==0)
ans--;
printf("%lld\n",ans);
}
return 0;
}