题解:
数位DP。
对于不同的进制直接数位DP就好了。
在数位dp中比较基础。
通过状压来xor值,使得表示每个数字出现奇数次/偶数次.
注意的就是 去除 00 0000 这些数的影响。
代码:
#include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 2e5 + 100; LL dp[11][80][2000][2]; /// k len state int sta[N]; LL dfs(int len, int state, int pre, int k, int lim){ if(!lim && ~dp[k][len][state][pre]) return dp[k][len][state][pre]; if(len == 0) return state == 0; int up = k - 1; if(lim) up = sta[len]; LL ans = 0; for(int i = 0; i <= up; ++i){ if(pre == 0 && len != 1 && i == 0) ans += dfs(len-1, state, 0, k, lim && (i == up)); else ans += dfs(len-1, state^(1<<i), 1, k, lim && (i==up)); } if(!lim) dp[k][len][state][pre] = ans; return ans; } LL cal(LL x, int k){ if(x == 0) return 0; int top = 0; while(x){ sta[++top] = x % k; x /= k; } return dfs(top, 0, 0, k, 1); } int main(){ memset(dp, -1, sizeof dp); int q; scanf("%d", &q); int b; LL l, r; while(q--){ scanf("%d%lld%lld", &b, &l, &r); printf("%lld\n", cal(r, b) - cal(l-1, b)); } return 0; }