BZOJ2190 [SDOI2008]仪仗队(洛谷P2158)

欧拉函数

BZOJ题目传送门
洛谷题目传送门

看出来后就变成套路题了。

能看到的点的横坐标和纵坐标肯定互质。那么转化一下就变成 n1i=1n1j=1[(i,j)=1] ∑ i = 1 n − 1 ∑ j = 1 n − 1 [ ( i , j ) = 1 ] 。然后想上什么上什么。。。

把原式拆成 2n1i=1ij=1[(i,j)=1] 2 ∑ i = 1 n − 1 ∑ j = 1 i [ ( i , j ) = 1 ] ,即 2n1i=1φ(i) 2 ∑ i = 1 n − 1 φ ( i ) ,然后前缀和算一波就好了,答案要加1( i=j=1 i = j = 1 的情况,前面的 2φ(1) 2 φ ( 1 ) 其实是算 (1,0) ( 1 , 0 ) (0,1) ( 0 , 1 ) 两个点的)。注意特判 n=1 n = 1 的情况。

代码:

#include
#include
#include
#define N 40005
using namespace std;
int n,phi[N];
inline int Make(){
    for (int i=1;i<=n;i++) phi[i]=i;
    for (int i=2;i<=n;i+=2) phi[i]>>=1;
    for (int i=3;i<=n;i+=2)
        if (phi[i]==i)
            for (int j=i;j<=n;j+=i)
                phi[j]=phi[j]/i*(i-1);
    for (int i=2;i<=n;i++) phi[i]+=phi[i-1];
    return n-1?phi[n-1]*2+1:0;
}
int main(){ return scanf("%d",&n),printf("%d\n",Make()),0; }

你可能感兴趣的:(洛谷,BZOJ,数论---欧拉定理/函数,蒟蒻zxl的Blog专栏)