1. 程式人生 > >神炎皇——解題報告

神炎皇——解題報告

題目連結http://132.232.5.128:666/problem/110 題目大意:對於一個整數對 (a,b),若滿足 a+b≤n且 a+b是a * b的因子,則稱為神奇的數對。問這樣的數對共有多少。 題目分析: 1.整除一類的題,我們很快能想到的就是GCD,我們可以利用gcd將式子化簡,a+b|a * b,設d=gcd(a,b),a’=a/d,b’=b/d。那麼(a’+b’) * d|a’ * b’ * d * d,所以 (a’+b’)|a’ * b’ * d,而根據輾轉相除法,gcd=(a’+b’,a’)=gcd(a’+b’,b’)=gcd(a’+b’,a’ * b’)=1。所以我們得到了(a’+b’)|d。 2.因為(a’+b’) * d≤n,所以(a’+b’)≤√n。若(a’+b’)=k,那麼合法的d就有n/k ^ 2個。而合法的a’,b’就有φ(k)個,所以答案就要加上n/k ^ 2 * φ(k)。 3.於是我們列舉一下所有的k就行了。 正解程式

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath> 

using namespace std;
typedef long long ll;
const ll maxn=10000010;
ll n,ans;
ll count1=0,prime[maxn],phi[maxn];
bool vis[maxn];
int main()
{
	scanf("%lld",&n);
	ll Max=sqrt(n); 
	for(ll i=2;i<=Max;i++)
	{
		if(!vis[i])
		{
			prime[++count1]=i;
			phi[i]=i-1;
		}
		for(ll j=1;j<=count1 && i*prime[j]<=Max;j++)
		{
			vis[i*prime[j]]=true;
			if(i%prime[j]==0)
			{
				phi[i*prime[j]]=phi[i]*prime[j];
				break;
			}
			phi[i*prime[j]]=phi[i]*(prime[j]-1);
		}
		ans+=n/i/i*phi[i];
	}
	printf("%lld\n",ans);
	
	return 0;
}