[SDOI2008]仪仗队
这道题是一道数论题qwq。首先当我们把队伍里面的每一个人当成平面直角坐标系里面的点,那么这题就是求斜率不同。
什么是斜率?前面说了在平面直角坐标系中,我们将C君看为原点,那么每一个点(x,y)都有一个与之对应的y=kx,所谓斜率就是指这里的k=x/y。那么对应的k=x*p/y*p,这样的(x,y)与(x*p,y*p)我们就只保留一个。那么题目就变成了找寻横纵坐标互质的点对。又因横纵坐标的特殊性,就先不考虑,最后再加上2就可以了。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; long long read(){ long long res=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ res=res*10+(ch-'0'); ch=getchar(); } return res*f; } long long n,ans,pri[40005],phi[40005],tot; bool vis[40005]; int main(){ n=read();n--; if(n==1||n==0){ cout<<0;return 0; } phi[1]=phi[0]=1; for(int i=2;i<=n;++i){ if(!vis[i]){ pri[++tot]=i; phi[i]=i-1; } for(int j=1,p;(p=pri[j]*i)<=n&&j<=tot;++j){ vis[p]=1; if(i%pri[j]){ phi[p]=phi[i]*(pri[j]-1); } else{ phi[p]=phi[i]*pri[j];break; } } phi[i]+=phi[i-1]; } cout<<phi[n]*2+1; return 0; }