SPOJ IGAME(Interesting Game-博弈+数位dp)
原创
©著作权归作者所有:来自51CTO博客作者mb62d7cd05038ca的原创作品,请联系作者获取转载授权,否则将追究法律责任
IGAME - Interesting Game
no tags
Alice and Bob play an interesting game and the game is played on a number.
So a player, on his chance, can choose any non zero digit of the number and decrease the digit by any non zero amount such that the resulting digit remains non-negative. The player who gets all the digits of the number 0 wins. Both play optimally and Alice starts first. Now tell how many numbers are there between A and B on which if the game is played Alice wins and also find how many numbers are there where Bob wins. On every number between A and B, Alice plays first on that number .
Input Format
The Input line consists of T test cases. On each line there are two numbers A and B.
Output Format
The Output line consists of T lines each having two numbers.
Constraints:
1 ≤ T ≤ 10000
1 ≤ A ≤ B ≤ 1018
Sample Input
2
1 10
101 110
Sample Output
10 0
8 2
Explanation
In the first case the first player Alice will always win because she can reduce any digit to 0.
In the second case the second player Bob will win on 2 numbers 101 and 110. Rest Alice will win.
显然Alice赢当且仅当xor和!=0
直接数位dp
#include<bits/stdc++.h>
using namespace std;
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma
#define
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
ll f[22][22];
int c[22];
ll calc(ll n) {
int len=0;
if (!n) return 1;
while(n) c[++len]=n%10,n/=10;
For(i,len/2) swap(c[i],c[len-i+1]);
ll v=0,ans=0;
For(i,len) {
MEM(f)
Rep(j,c[i]) f[i][v^j]++;
Fork(j,i,len-1) {
Rep(k,20)
if (f[j][k])
Rep(l,10) f[j+1][k^l]+=f[j][k];
}
v^=c[i];
ans+=f[len][0];
}return ans+(v==0);
}
int main()
{
// freopen("spojIGAME.in","r",stdin);
// freopen(".out","w",stdout);
int T=read();
while(T--) {
ll a,b;
cin>>a>>b;
ll ans=calc(b)-calc(a-1);
ll ans2=b-a+1;
cout<<ans2-ans<<' '<<ans<<endl;
}
return 0;
}