题目描述见链接 .
按位处理, 设当前进制为 , 计算第 位的答案,
有 这道题 作基础, 可以知道形如 的循环节长度为 ,
循环节内部最长连续数字为 个,
完整的循环节个数为 , 对答案贡献为 .
还剩余一个不完整的循环节, 长度为 , 在这个循环节中, 将形如 看成新的循环节,
得到新的 , , 对答案贡献为 ,
然而还是会剩下不完整的形如 这样的小循环节, 长度为 ,
对 答案贡献 为 .
#include<bits/stdc++.h>
#define reg register
int N;
int B;
int Ans;
int Case_cnt;
int pw[20][21];
void Work(){
scanf("%d%d", &N, &B);
Ans = 0;
for(reg int bit = 0; pw[B][bit] <= N+1; bit ++){
int cir_len = pw[B][bit+1];
int cir_num = (N+1) / cir_len;
Ans += pw[B][bit] * cir_num * B*(B-1)/2;
int sca_num = (N+1) % cir_len;
if(!sca_num) continue ;
cir_len = pw[B][bit];
cir_num = sca_num / cir_len;
Ans += cir_len * cir_num*(cir_num-1)/2;
int left_num = sca_num % cir_len;
Ans += left_num * cir_num;
}
printf("Case #%d: %d
", ++Case_cnt, Ans);
}
void Init(){
for(reg int i = 2; i <= 11; i ++){
pw[i][0] = 1;
for(reg int j = 1; j <= 20; j ++) pw[i][j] = pw[i][j-1] * i;
}
}
int main(){
int T;
scanf("%d", &T);
Init();
while(T --) Work();
return 0;
}