2021.08.06(欧拉函数)

201. 可见的点 - AcWing题库

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int maxn = 1002;
bool vis[maxn]; // 0 为素数 1 为非素数
int tot, phi[maxn], prime[maxn];

void CalPhi() {
    vis[1] = 1, phi[1] = 1;
    for (int i = 2; i < maxn; ++i) {
        if (!vis[i]) prime[tot++] = i, phi[i] = i - 1;
        for (int j = 0; j < tot; ++j) {
            if (i * prime[j] > maxn) break;
            vis[i * prime[j]] = 1;
            if (i % prime[j] == 0) {
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            } else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
        }
    }
}
signed main(void){
    int n;
    scanf("%lld",&n);
    CalPhi();
    int j=1;
    while(n--){
        //printf("%lld\n",n);
        int m;
        scanf("%lld",&m);
        int sum=0;
        for(int i=1;i<=m;i++){
            sum+=phi[i];
        }
        sum*=2;
        sum++;
        printf("%lld %lld %lld\n",j,m,sum);
        j++;
    }
}
View Code

注:从可见点的表示入手,这样一来,就能发现x和y必须满足x和y互质,然后对称分析

220. 最大公约数 - AcWing题库

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int maxn = 10000001;
bool vis[maxn]; // 0 为素数 1 为非素数
int tot, phi[maxn], prime[maxn];

void CalPhi() {
    vis[1] = 1, phi[1] = 1;
    for (int i = 2; i < maxn; ++i) {
        if (!vis[i]) prime[tot++] = i, phi[i] = i - 1;
        for (int j = 0; j < tot; ++j) {
            if (i * prime[j] > maxn) break;
            vis[i * prime[j]] = 1;
            if (i % prime[j] == 0) {
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            } else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
        }
    }
}
int s[maxn];
signed main(void){
    int n;
    scanf("%lld",&n);
    CalPhi();
    int sum=0;
    for(int i=2;i<=n;i++){
        s[i]=s[i-1]+phi[i];

    }
    for(int i=0;i<tot;i++){
        if(prime[i]<=n){
        int p=n/prime[i];
        sum+=2*s[p]+1;
        }
    }
    printf("%lld\n",sum);
}
View Code

注:gcd(x,y)=p,就是转化为gcd(x/p,y/p)=1,进而转化为在1~n/p区间上进行查找

 

posted @ 2021-08-06 15:56  bonel  阅读(31)  评论(0)    收藏  举报