[SDOI2008]仪仗队

题目链接:

  P2158 [SDOI2008]仪仗队

solution:

  许久没学数论了,刚好刷到这题,复习下欧拉筛吧.板子贴下来就跑~

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#define R register
#define next exnttttttttt
#define debug puts("mlg")
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
inline ll read();
inline void write(ll x);
inline void writesp(ll x);
inline void writeln(ll x);
ll n;
ll ans=3;
ll prime[50000],phi[50000],tot;
bool v[55000];
inline void euler(){
    v[1]=true;
    for(R ll i=2;i<=n;i++){
        if(!v[i]){
            prime[++tot]=i;phi[i]=i-1;
        }
        for(R ll j=1;j<=tot&&i*prime[j]<=n;j++){
            
            v[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);
        }
    }
}
int main(){
    n=read();
    if(n==1){writeln(0);return 0;}
    if(n==2){writeln(1);return 0;}
    euler();
    for(R ll i=2;i<n;i++) ans+=phi[i]<<1;
    writeln(ans);
}
inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;}
inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');}
inline void writesp(ll x){write(x);putchar(' ');}
inline void writeln(ll x){write(x);putchar('
');}
原文地址:https://www.cnblogs.com/ylwtsq/p/13367108.html