light 1007
题意:求区间所有数的欧拉函数的平方和:
思路:线性筛求欧拉函数,最后前缀和。
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
int phi[5000050];
ull sum[5000050];
void phi_table(int n, int* phi) {
for (int i = 2; i <= n; i++) phi[i] = 0;
phi[1] = 1;
for (int i = 2; i <= n; i++)
if (!phi[i])
for (int j = i; j <= n; j += i) {
if (!phi[j]) phi[j] = j;
phi[j] = phi[j] / i * (i - 1);
}
}
int main(){
int t,cas = 0;scanf("%d",&t);
phi_table(5000000,phi);
for(int i = 2 ; i <= 5000000 ; i++){
sum[i] = sum[i-1] + ull(phi[i])*phi[i];
}
while(t--){
int a,b;
scanf("%d %d",&a,&b);
printf("Case %d: %llu\n",++cas,sum[b] - sum[a-1]);
}
return 0;
}
普通求欧拉函数:
int euler_phi(int n) {
int m = int(sqrt(n + 0.5));
int ans = n;
for (int i = 2; i <= m; i++)
if (n % i == 0) {
ans = ans / i * (i - 1);
while (n % i == 0) n /= i;
}
if (n > 1) ans = ans / n * (n - 1);
return ans;
}
线性筛:
void phi_table(int n, int* phi) {
for (int i = 2; i <= n; i++) phi[i] = 0;
phi[1] = 1;
for (int i = 2; i <= n; i++)
if (!phi[i])
for (int j = i; j <= n; j += i) {
if (!phi[j]) phi[j] = j;
phi[j] = phi[j] / i * (i - 1);
}
}