給一個十進制的數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;
}