Fibonacci And Gcd
Problem:1507
Time Limit:1000ms
Memory Limit:65535K
Description
给定n和m求解上述式子
Input
第一行一个T,代表有T组数据,1<=T<=10
接下来T行每行两个数字n和m,1<=n,m<=1e6
Output
输出答案,每行代表一个答案
Sample Input
2
2 2
3 3
Sample Output
4
10
从打表找规律会发现 gcd(Fi,Fj)=Fgcd(i,j) g c d ( F i , F j ) = F g c d ( i , j )
然后我们就可以开始推导了
#include
#include
#include
#include
#include
#include
using namespace std;
const long long mod=1e9+7;
const int N=1e6+5;
long long f[N];
long long sum[N];
int vis[N];
int mu[N];
int prime[N];
int cnt;
void Init()
{
memset(vis,0,sizeof(vis));
mu[1] = 1;
cnt = 0;
for(int i=2; iif(!vis[i])
{
prime[cnt++] = i;
mu[i] = -1;
}
for(int j=0; j1;
if(i%prime[j]) mu[i*prime[j]] = -mu[i];
else
{
mu[i*prime[j]] = 0;
break;
}
}
}
f[1]=1;
f[2]=1;
for(int i=3; i1]+f[i-2])%mod;
for(int i=1; i1]+mu[i];
}
long long get(int n,int m)
{
long long ans=0;
for(int i=1,last; i<=min(n,m); i=last+1)
{
last=min(n/(n/i),m/(m/i));
ans+=(sum[last]-sum[i-1])*(n/i)*(m/i);
ans=(ans+mod)%mod;
}
return ans;
}
int main()
{
Init();
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
long long ans=0;
for(int i=1; i<=min(n,m); i++)
{
ans=(ans%mod+f[i]%mod*get(n/i,m/i)%mod+mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}