给一个十进制的数n,把他转换成b进制,求从1到这个数n在b进制下每个数的每位数之和的总和。
题解给的暴力打表就行了。
我的解法就是找规律,大概就是先求n/b,这样就知道n的个位数出现了几轮,乘上1到9之和再乘上每个个位数出现的次数1,继续算剩下的没有出现完成一轮的个位数之和,顺便再加上十位,百位。。上的数字之和,还要乘上那个出现次数1,然后n/=b,并且n–(这里的n在个位数算过,所以删掉一),出现次数*b,就相当于把原来的十位数当个位数了。仔细想想还是不难的,随便交一发就过了也不知道自己推错没有,不过时间确实只有打表的十分之一。
#include <bits/stdc++.h>
#define eps 1e-14
#define pi acos(-1)
#define ll long long
#define RD T*(rand()*2-RAND_MAX)
#define Drand (long double)rand()/RAND_MAX
#define LINF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=5e5+50;
const long long mod=1e18;
ll MOD(ll a,ll m){return a>m?a%m+m:a;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
int n;
int b;
int cal()
{
int dif=10;
int c=1;
int ans=0;
int add=(b-1)*b/2;
// cout<<add<<endl;
while(n>0){
int ten=n/b;
// cout<<"ten = "<<ten<<endl;
if(ten>=0){
ans+=add*ten*c;
}
int ge=n%b;
// cout<<"ge = "<<ge<<endl;
ans+=(1+ge)*(ge)/2*c;
int pp=ten,ansp=0;
while(pp>0){
ansp+=pp%b;
pp/=b;
}
ans+=ansp*(ge+1)*c;
// cout<<"ans = "<<ans<<endl;
n/=b;
n--;
c*=b;
}
return ans;
}
int main()
{
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
int t;
scanf("%d",&t);
int cas=1;
while(t--){
scanf("%d",&n);
scanf("%d",&b);
printf("Case #%d: %d\n",cas++,cal());
}
return 0;
}