题意:给出法雷级数定义
F2 = {1/2}
F3 = {1/3, 1/2, 2/3}F4 = {1/4, 1/3, 1/2, 2/3, 3/4}
F5 = {1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5} 求f[n]组法雷级数分数的个数。
不难发现就是欧拉函数前n项的和。运用递推求欧拉函数即可。再发个快的,留着比赛做模板。
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define maxn 1000008 long long phi[maxn]; void getphi() { for(int i=1; i<maxn; i++) phi[i]=i; for(int i=2; i<maxn; i+=2) phi[i]>>=1; for(int i=3; i<maxn; i+=2) if(phi[i]==i) { for(int j=i; j<maxn; j+=i) phi[j]=phi[j]/i*(i-1); } for(int i=3; i<maxn; i++) phi[i]+=phi[i-1]; } int main() { getphi(); int n; while(~scanf("%d",&n),n) printf("%lld\n",phi[n]); return 0; }网上找的快的79ms
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #ifdef unix #define lld "%lld" #else #define lld "%I64d" #endif using namespace std; const int maxn=1000005; int n; int prime[maxn/10],prime_size; bool prime_flag[maxn]= {1,1}; int phi[maxn]= {0,1}; long long ans[maxn]; void mk_prime() { for(int i=2; i<=n; i++) { if(prime_flag[i]==0) { prime[prime_size++]=i; phi[i]=i-1; } for(int j=0; j<prime_size && i*prime[j]<=n; j++) { prime_flag[i*prime[j]]=true; 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 main() { n=maxn-2; mk_prime(); for(int i=1; i<maxn; i++) ans[i]=ans[i-1]+phi[i]; while(true) { scanf("%d",&n); if(n==0) return 0; printf(lld"\n",ans[n]-1ll); } return 0; }