1. 程式人生 > >#尤拉函式,數論#hdu 6434 Problem I. Count

#尤拉函式,數論#hdu 6434 Problem I. Count

題目

i=1nj=1n[gcd(i+j,ij)==1]\sum_{i=1}^{n}\sum_{j=1}^n[gcd(i+j,i-j)==1]

分析

原式=i=1nj=1n[gcd(2i,ij)==1]=i=1nj=1n[gcd(2i,j)==1]\sum_{i=1}^{n}\sum_{j=1}^n[gcd(2i,i-j)==1]=\sum_{i=1}^{n}\sum_{j=1}^n[gcd(2i,j)==1]

ii是偶數,也就是求φ(j)\varphi(j),否則,也就是求φ(j)÷2\varphi(j)\div 2,那麼跑字首和就可以了

程式碼

#include <cstdio>
#define rr register
using namespace std;
const int N=20000001;
int v[N],prime[100001],cnt; long long phi[N];
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (c<48||c>57) c=getchar()
; while (c>47&&c<58) ans=(ans<<3)+(ans<<1)+c-48,c=getchar(); return ans; } inline void pre(){ for (rr int i=2;i<N;++i){ if (!v[i]) v[i]=prime[++cnt]=i,phi[i]=i-1; for (rr int j=1;prime[j]*i<=N;++j){ v[i*prime[j]]=prime[j]; phi[i*prime[j]]=phi[i]*(prime[
j]-(i%prime[j]>0)); if (i%prime[j]==0) break; } } for (rr int i=2;i<N;++i){ if (i&1) phi[i]>>=1; phi[i]+=phi[i-1]; } } void print(long long ans){ if (ans>9) print(ans/10); putchar(ans%10+48); } signed main(){ pre(); for (rr int t=iut();t;--t) print(phi[iut()]),putchar(10); return 0; }