题意:求L~R所有的数的l~r进制的f(x,k进制), 如果x是回文串f(x,k进制) = k, 否则等于1;
枚举进制,求出每一种情况,注意膜k,不是膜10,T_T调了好久才发现错在这;
题解:dp[pos][start][similar][basic]表示basic进制下,处理到完pos位,从start位开始,similar状态下回文串的个数。则记忆化搜索下即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int dp[32][32][2][37];
int tmp[32], dight[32];
int dfs(int pos, int start, bool similar, bool limit, int basic)
{
if(!pos) return similar;
int &A = dp[pos][start][similar][basic];
if(~A && !limit) return A;
int up = limit ? dight[pos] : basic - 1, res = 0;
for(int i = 0;i <= up;i ++) {
tmp[pos] = i;
if(i == 0 && pos == start) {
res += dfs(pos-1, start-1, similar, limit && i == dight[pos], basic);
} else if(similar && pos < start / 2 + 1) {
res += dfs(pos-1, start, similar && i == tmp[start+1-pos], limit && i == dight[pos], basic);
} else {
res += dfs(pos-1, start, similar, limit && i == dight[pos], basic);
}
}
if(!limit) A = res;
return res;
}
int solve(int n, int k)
{
int cnt = 0;
while(n) {
dight[++cnt] = n % k;
n /= k;
}
return dfs(cnt, cnt, 1, 1, k);
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0);
int T, Case = 0;
int L, R, l, r;
memset(dp, -1, sizeof(dp));
cin >> T;
while(T --) {
cin >> L >> R >> l >> r;
ll res = 0;
for(int i = l;i <= r;i ++) {
ll t = solve(R, i) - solve(L-1, i);
res += t * i + R - L + 1 - t;
}
cout << "Case #" << ++Case << ": ";
cout << res << '\n';
}
return 0;
}