@ZYK1997
2015-04-02T11:53:20.000000Z
字数 8143
阅读 949
数论
推导如下:
化简到这里,我们不禁想起了另一道经典题目:
给定n,求
解决方法:通过观察(打表)、猜想……我们可以发现,对于很多
我们再回到这道题来。
我们会发现,
粘上代码:
#include<bits/stdc++.h>
using namespace std;
const int N=100000,M=N+5;
#define LL long long
int 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;
}