題目描述:
給定乙個正整數n,求1~n中每個數的尤拉函式之和。
輸入格式
共一行,包含乙個整數n。
輸出格式
共一行,包含乙個整數,表示1~n中每個數的尤拉函式之和。
資料範圍
1≤n≤10^6
輸入樣例:
6
輸出樣例:
12
分析:
求1到n中每個數的尤拉函式之和,顯然乙個個呼叫計算尤拉函式的公式時間複雜度是極高的。可以通過修改素數的線性篩法的**來實現尤拉函式的求和功能,線性篩法將每個數都篩了一遍,所以可以在篩的過程中計算出尤拉函式。尤拉函式phi(n) = n(1 - 1/p1 +... + 1/pk),對於素數而言,小於它的數都與之互質,所以i為質數時,phi(i) = i - 1.當i去篩掉t = i*primes[j]時,分為i能被primes[j]整除和不能被其整除兩種情況。primes[j] | i時,primes[j]為i的因子,所以t**現的質數在i中都出現了,即phi(i) = i(1 - 1 / p1 + ... + 1 / pk),phi(t) = t(1 - 1 / p1 + ... + 1 / pk) = phi(i) * t / i = phi(i)*primes[j]。i不能被primes[j]整除時,i必然與primes[j]互質(因為primes儲存的都是質數),則t中恰好比i多乙個primes[j]的質因子,即phi(i) = i(1 - 1 / p1 + ... + 1 / pk),phi(t) = t(1 - 1 / p1 + ... + 1 / pk) (1 - 1 / primes[j])= phi(i) * (1 - 1 / primes[j]) * t / i = phi(i)*(primes[j] - 1)。
#include using namespace std;
typedef long long ll;
const int maxn = 1000005;
int primes[maxn],euler[maxn],cnt;
bool st[maxn];
void get_eulers(int n)
for(int j = 0;primes[j] <= n / i;j++)
euler[t] = euler[i] * (primes[j] - 1);}}
}int main()
AcWing 874 篩法求尤拉函式
這道題並不簡單,你要會用尤拉篩去篩尤拉數。說說思路。首先和尤拉篩質數一樣,先把質數篩出來,質數的尤拉數為本身減1,因為質數與前面的數都互質。然後用質數去更新下乙個數,篩除合數的同時,去更新合數的尤拉數,其中有幾個特殊的地方。include using namespace std const int ...
874 篩法求尤拉函式
給定乙個正整數n,求1 n中每個數的尤拉函式之和。輸入格式 共一行,包含乙個整數n。輸出格式 共一行,包含乙個整數,表示1 n中每個數的尤拉函式之和。資料範圍 1 n 106 輸入樣例 6輸出樣例 12想法 涉及到在範圍內的質數,則使用線性篩法 include using namespace std...
874 篩法求尤拉函式
給定乙個正整數 n 求 1 n 中每個數的尤拉函式之和。共一行,包含乙個整數 n 共一行,包含乙個整數,表示 1 n 中每個數的尤拉函式之和。資料範圍 1 n 10 6 輸入樣例 6輸出樣例 12eratosthenes篩法求尤拉函式 problem 篩法求尤拉函式 contest acwing u...