@ZYK1997
2015-04-02T03:53:20.000000Z
字数 8143
阅读 1057
数论
推导如下:
化简到这里,我们不禁想起了另一道经典题目:
给定n,求
解决方法:通过观察(打表)、猜想……我们可以发现,对于很多
我们再回到这道题来。
我们会发现,
粘上代码:
#include<bits/stdc++.h>using namespace std;const int N=100000,M=N+5;#define LL long longint n,m;bool cjx[M];int prime[M],tot;int phi[M];LL sum[M];void pre(){tot=0;phi[1]=1;for(int i=2;i<=N;i++){if(!cjx[i]) {prime[tot++]=i;phi[i]=i-1;}for(int j=0;j<tot;j++){if(i*prime[j]>N) break;cjx[i*prime[j]]=true;if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;} else {phi[i*prime[j]]=phi[i]*(prime[j]-1);}}}for(int i=1;i<=N;i++) sum[i]=sum[i-1]+phi[i];}LL solve(int n,int m){LL re=0;for(int i=1,j;i<=min(n,m);i=j+1){j=min(n/(n/i),m/(m/i));re+=(sum[j]-sum[i-1])*(n/i)*(m/i);}return re;}int main(){pre();int T; scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);cout<<solve(n,m)<<endl;}return 0;}
我们换一个思路,考虑
推导如下:
#include<bits/stdc++.h>using namespace std;const int N=100000;const int M=100005;typedef long long LL;bool cjx[M];int prime[M],tot;int mu[M];LL g[M],sum[M];void pre(){tot=0;mu[1]=1; g[1]=1;for(int i=2;i<=N;i++){if(!cjx[i]){prime[tot++]=i;mu[i]=-1;g[i]=-i*(i-1);}for(int j=0;j<tot;j++){if(i*prime[j]>N) break;cjx[i*prime[j]]=true;if(i%prime[j]==0){mu[i*prime[j]]=0;g[i*prime[j]]=g[i]*prime[j];break;} else {mu[i*prime[j]]=-mu[i];g[i*prime[j]]=g[i]*g[prime[j]];}}}for(int i=1;i<=N;i++) sum[i]=sum[i-1]+g[i];}LL solve(int n,int m){LL re=0;for(int i=1,j;i<=min(n,m);i=j+1){j=min(n/(n/i),m/(m/i));re+=(LL)(sum[j]-sum[i-1])*(n/i)*(n/i+1)*(m/i)*(m/i+1);}return re>>2;}int main(){pre();int T; scanf("%d",&T);while(T--){int n,m;scanf("%d%d",&n,&m);cout<<solve(n,m)<<endl;}return 0;}
解析:
首先转化思路,我们思考
设
则
我们将
所以我们只需要思考怎么计算
而我们知道
那么我们通过数列化简、整理最终得到
问题解决了,我的代码比较丑,大家意识流即可……
#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;typedef long long LL;LL pow(LL a,LL b){LL re=1;for(;b;b>>=1,a*=a)if(b&1) re*=a;return re;}int main(){LL n; cin>>n;LL ans=1;for(int i=2;i*i<=n;i++){LL a=0;while(n%i==0){a++; n/=i;}if(a==0) continue;LL b=pow(i,a-1);ans*=(a+1)*b*i-a*b;}ans*=2*n-1;cout<<ans<<endl;return 0;}