题意:A-B中有多少个数满足所有数位上出现的数字,数字为奇数的出现偶数次,数字为偶数的出现奇数次
数位盲打(同hdu352)
0-9每个数字出现的次数状态压缩,0没出现,1出现奇数次,2出现偶数次
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <vector> 7 #include <ctime> 8 #include <queue> 9 #include <list> 10 #include <set> 11 #include <map> 12 using namespace std; 13 #define INF 0x3f3f3f3f 14 typedef long long LL; 15 16 int bit[25]; 17 LL dp[25][60000]; 18 int Pow(int n, int p) 19 { 20 int res = 1; 21 while(p) 22 { 23 if(p & 1) 24 res *= n; 25 n *= n; 26 p>>=1; 27 } 28 return res; 29 } 30 int change(int state, int n) 31 { 32 int N = n, State = state; 33 while(N--) 34 { 35 State /= 3; 36 } 37 int b = State % 3; 38 if(b<2) 39 return state + Pow(3, n); 40 else 41 return state - Pow(3, n); 42 } 43 int check(int state) 44 { 45 int len=-1, b; 46 while(state) 47 { 48 len++; 49 b = state % 3; 50 if((len & 1)==1 && b == 1) 51 return 0; 52 if((len & 1)==0 && b == 2) 53 return 0; 54 state /= 3; 55 } 56 return 1; 57 } 58 LL dfs(int len, int state, int flag) 59 { 60 if(len < 0) 61 return check(state); 62 if(dp[len][state] >= 0 && flag) 63 return dp[len][state]; 64 LL sum = 0; 65 int te = flag ? 9 : bit[len]; 66 for(int i = 0; i <= te; i++) 67 { 68 sum+=dfs(len-1, (state==0&&i==0)?0:change(state,i), flag||i<te); 69 } 70 if(flag) 71 dp[len][state] = sum; 72 return sum; 73 } 74 LL solve(LL n) 75 { 76 int len = 0; 77 while(n) 78 { 79 bit[len++] = n % 10; 80 n /= 10; 81 } 82 return dfs(len-1, 0, 0); 83 } 84 int main() 85 { 86 int t; 87 LL A, B; 88 scanf("%d", &t); 89 memset(dp, -1, sizeof(dp)); 90 while(t--) 91 { 92 scanf("%lld %lld", &A, &B); 93 LL res = solve(B) - solve(A - 1); 94 printf("%lld ", res); 95 } 96 return 0; 97 }