-
[1545] 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的思路倒是很容易的就想出来了,但是没想到一个小细节,让我查了一天的数据,。。。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
__int64 dp1[16][20],dp2[16][20];
char s1[20],s2[20];
int main()
{
//freopen("data.in","r",stdin);
memset(dp1,0,sizeof(dp1));
memset(dp2,0,sizeof(dp2));
for(int i=0;i<=9;i++)
{
dp1[i][1] = dp2[i][1] = 1;
}
dp1[0][0] = dp2[0][0] = 1;
for(int i=2;i<=19;i++)
{
for(int j=1;j<=9;j++)
{
for(int k = 0;k<=15;k++)
{
int u = k^j;
dp1[u][i]+=dp2[k][i-1]; //不带前导0
}
}
for(int j=0;j<=9;j++)
{
for(int k=0;k<=15;k++)
{
int u = k^j;
dp2[u][i]+=dp2[k][i-1]; //带前导0
}
}
}
while(scanf("%s %s",s1,s2)!=EOF)
{
int l2 = strlen(s2);
int l1 = strlen(s1);
if(l2>2)
{
printf("0\n");
continue;
}
int s= 0;
for(int i=0;i<=l2-1;i++)
{
s = s*10+s2[i]-'0';
}
if(s>15)
{
printf("0\n");
continue;
}
__int64 res = 0;
for(int i=1;i<=l1-1;i++)
{
res+=dp1[s][i];
}
int tag = 0;
for(int i=0;i<=l1-1;i++)
{
int dig = s1[i]-'0';
int t;
if(i==0)
{
t =1;
}else
{
t = 0;
}
for(int j=t;j<=dig-1;j++)
{
for(int k=0;k<=15;k++)
{
int x = tag^j;
x = x^k;
if(x==s)
{
res+=dp2[k][l1-1-i];
}
}
}
tag = tag^dig;
}
if(l1==1&&s==0)
{
res++;
}else
{
tag = 0;
for(int i=0;i<=l1-1;i++)
{
int dig = s1[i]-'0';
tag = tag^dig;
}
if(tag==s)
{
res++;
}
}
if(s==0)
{
res-=1;
}
printf("%I64d\n",res);
}
return 0;
}