rt,对于本题,这么写就可以过
#include<iostream>
#include<cstdio>
#include<cstring>
#define int long long
using namespace std;
int q, b, l, r;
int f[11][70][1024], a[1024];
//第一位表示进制,第二位表示位数,第三位表示是否符合条件
int dfs(int x, int now, int z, int up){
if(!x) return !now;
if(!z && !up &&f[b][x][now] != -1) return f[b][x][now];
int l, sum = 0;
if(up) l = a[x];
else l = b - 1;
for(int j = 0; j <= l; j++){
sum += dfs(x - 1, (z&&!j)?0:(now^(1<<j)), z&&!j, up&&(j == l));
}
if(!z && !up)f[b][x][now] = sum;
return sum;
}
int query(int x){
int len = 0, k = x;
while(k){
a[++len] = k % b;
k/=b;
}
return dfs(len, 0, 1, 1);
}
signed main(){
scanf("%lld", &q);
memset(f, -1, sizeof(f));
while(q--){
scanf("%lld%lld%lld", &b, &l, &r);
printf("%lld\n", query(r) - query(l - 1));
}
return 0;
}
但是按照我一般的习惯写会挂掉,其他数位dp这么写一般不会出错。
#include<iostream>
#include<cstdio>
#include<cstring>
#define int long long
using namespace std;
int q, b, l, r;
int f[11][70][1024][2][2], a[1024];
//第一位表示进制,第二位表示位数,第三位表示是否符合条件
int dfs(int x, int now, int z, int up){
if(!x) return !now;
if(f[b][x][now][z][up] != -1) return f[b][x][now][z][up];
int l, sum = 0;
if(up) l = a[x];
else l = b - 1;
for(int j = 0; j <= l; j++){
sum += dfs(x - 1, (z&&!j)?0:(now^(1<<j)), z&&!j, up&&(j == l));
}
f[b][x][now][z][up] = sum;
return sum;
}
int query(int x){
int len = 0, k = x;
while(k){
a[++len] = k % b;
k/=b;
}
return dfs(len, 0, 1, 1);
}
signed main(){
scanf("%lld", &q);
memset(f, -1, sizeof(f));
while(q--){
scanf("%lld%lld%lld", &b, &l, &r);
printf("%lld\n", query(r) - query(l - 1));
}
return 0;
}