按位求和问题
题意:给定两个十进制数x,y(y>=x&&y<=1e15),求转化为k进制后(2<=k<=10),区间数按位求和
分析:看的高逸涵的论文,思路无外乎就是根据1到K^x-1之间0-(k-1)所有数字出现的次数相同,以此快速求解,然后划分区间,合并答案
想了解可以自己看一下论文,很详细
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 5 ll getsum1(ll n,int k){ 6 ll b=1; 7 for(int i=0;i<n;i++)b*=k; 8 return b*n*(k-1)/2; 9 } 10 11 ll getsum(ll pre,ll n,int k){ 12 ll b=getsum1(n,k); 13 ll c=pre; 14 for(int i=0;i<n;i++) 15 c*=k; 16 return b+c; 17 } 18 19 ll solve(ll pre,ll n,int k){ 20 //n<k 21 if(n<k){ 22 ll ret=0; 23 for(int i=0;i<=n;i++)ret+=pre+i; 24 return ret; 25 } 26 ll tn=n,t=1,tot=0; 27 while(tn>=k){ 28 tot++; 29 t*=k; 30 tn/=k; 31 } 32 ll ret=0; 33 for(int i=0;i<tn;i++) 34 ret+=getsum(pre+i,tot,k); 35 ret+=solve(pre+tn,n-t*tn,k); 36 return ret; 37 } 38 39 ll judge(ll n,int k){ 40 ll ret=0; 41 for(int i=1;i<=n;i++){ 42 ll tn=i; 43 while(tn>0){ 44 ret+=tn%k; 45 tn/=k; 46 } 47 } 48 return ret; 49 } 50 51 int main(){ 52 cout<<judge(1000,7)<<endl; 53 cout<<solve(0,1000,7)<<endl; 54 return 0; 55 }