##思路
求连续范围内的最大公约数的和,为了降低时间复杂度,都是枚举最大公约数求和。
/* ********************************
Author : danmu
Created Time : 2016年08月01日 星期一 06时28分29秒
File Name : hdu5780.cpp
******************************** */
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <string>
#include <vector>
#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
#include <list>
#include <map>
#include <set>
#define rep(i,x,y) for(int i=x;i<=y;++i)
#define _rep(i,x,y) for(int i=x;i>=y;--i)
#define CL(S,x) memset(S,x,sizeof(S))
#define CP (S1,S2) memcpy(S1,S2,sizeof(S2))
#define ALL(x,S) for(x=S.begin();x!=S.end();++x)
#define ULL unsigned long long
#define PI 3.1415926535
#define INF 0x3f3f3f3f
#define LL long long
const int maxn = 1e6;
const int mod = 1e9 + 7;
const double eps = 1e-8;
using namespace std;
int phi[1000010];
LL sphi[1000010];
void init(){
for(int i=1;i<=maxn;++i) phi[i]=i;
for(int i=2;i<=maxn;i+=2) phi[i]/=2;
for(int i=3;i<=maxn;i+=2)
if(phi[i]==i)
for(int j=i;j<=maxn;j+=i)
phi[j]=phi[j]/i*(i-1);
for(int i=1;i<=maxn;++i){
sphi[i]=(sphi[i-1]+phi[i])%mod;
}
}
LL powMod(LL a,int b,int m){
LL ret=1;
while(b){
if(b&1) ret=(ret*a)%m;
a=a*a%m;
b/=2;
}
return ret;
}
int main(){
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int t;
init();
scanf("%d",&t);
while(t--){
int x,n;
LL ans=0;
scanf("%d%d",&x,&n);
if(x==1){
printf("0\n");
continue;
}
int next;
for(int i=1;i<=n;i=next+1){
next=n/(n/i);
LL zi=powMod(x,next+1,mod)-powMod(x,i,mod);
LL mu=powMod(x-1,mod-2,mod);
LL fac=((zi*mu%mod-(next-i+1))%mod+mod)%mod;
ans=(ans+(sphi[n/i]*2-1)*fac%mod)%mod;
}
printf("%I64d\n",ans);
}
return 0;
}
##总结
- g c d ( x a − 1 , x b − 1 ) = x g c d ( a , b ) − 1 gcd(x^{a}-1,x^{b}-1)=x^{gcd(a,b)}-1 gcd(xa−1,xb−1)=xgcd(a,b)−1
- n / i ( i ∈ { 1 到 n } ) 商 的 分 布 , i 到 n / ( n / i ) 的 商 相 等 n/i(i\in\{1到n\})商的分布,i到n/(n/i)的商相等 n/i(i∈{1到n})商的分布,i到n/(n/i)的商相等