1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #include <cstdio> #include <algorithm> typedef long long int ll; const int mod=(int)1e9+7; inline int inc(int x,int y) {x+=y;return x>=mod?x-mod:x;} inline int dec(int x,int y) {x-=y;return x<0?x+mod:x;} inline int mul(int x,int y) {return (ll)x*y%mod;} inline int qpow(int n,int k) { int ans=1; while(k) { if(k&1) ans=mul(ans,n); n=mul(n,n);k>>=1; } return ans; } inline int calc(int n,int m) { m=std::min(n,m); return inc(mul(mul(m+1,m+2),qpow(2,mod-2)),(m+1<=n)?mul(m+1,n-m):0); } int upn[65],upm[65],cnt=0,f[65][2][2]; int main() { int t,k;scanf("%d%d",&t,&k); while(t--) { ll n,m;scanf("%lld%lld",&n,&m);m=std::min(n,m); int ans=inc(mul(mul((m+1)%mod,(m+2)%mod),qpow(2,mod-2)),(m+1<=n)?mul((m+1)%mod,(n-m)%mod):0); if(k==1) {printf("%d\n",ans);continue;} cnt=0;while(n||m) {++cnt;upn[cnt]=n%k;n/=k;upm[cnt]=m%k;m/=k;} std::reverse(upn+1,upn+1+cnt);std::reverse(upm+1,upm+1+cnt); memset(f,0,sizeof(f));f[0][1][1]=1; for(register int i=1;i<=cnt;++i) { f[i][0][0]=inc(f[i][0][0],mul(f[i-1][0][0],mul(mul(k,k+1),qpow(2,mod-2)))); f[i][0][0]=inc(f[i][0][0],mul(f[i-1][0][1],calc(k-1,upm[i]-1))); f[i][0][0]=inc(f[i][0][0],mul(f[i-1][1][0],calc(upn[i]-1,k-1))); f[i][0][0]=inc(f[i][0][0],mul(f[i-1][1][1],calc(upn[i]-1,upm[i]-1))); f[i][0][1]=inc(f[i][0][1],mul(f[i-1][0][1],k-upm[i])); f[i][0][1]=inc(f[i][0][1],mul(f[i-1][1][1],upn[i]>=upm[i]?upn[i]-upm[i]:0)); f[i][1][0]=inc(f[i][1][0],mul(f[i-1][1][0],std::min(upn[i]+1,k))); f[i][1][0]=inc(f[i][1][0],mul(f[i-1][1][1],std::min(upn[i]+1,upm[i]))); f[i][1][1]=inc(f[i][1][1],f[i-1][1][1]*(upm[i]<=upn[i])); } ans=dec(ans,inc(inc(inc(f[cnt][0][0],f[cnt][0][1]),f[cnt][1][0]),f[cnt][1][1])); printf("%d\n",ans); } return 0; }
|