Link
Solve
通过观察发现,可以被看到的人必须满足(gcd(x,y)=1)证明也很简单,如果(x,y)不互质的话,那么一定会有((x/gcd(x,y),y/gcd(x,y)))把((x,y))挡住,换句话说,如果(gcd(x,y))等于1,那么它一定可以把所有的((kx,ky))都挡住,所以我们只需要求出与(x,y)互质对的对数即可。
我们自然而然就想到了欧拉函数
介于这张图是对称的,所以只要统计下三角的数量最后( imes2)就是最后的答案,第一行第一列和((2,2))要特判
Code
#include<bits/stdc++.h>
using namespace std;
const int maxn=40005;
int N;
typedef long long LL;
int p[maxn],ans;
inline int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
int main(){
freopen("P2158.in","r",stdin);
freopen("P2158.out","w",stdout);
N=read();
if(N==1){printf("0
");return 0;}
for(int i=1;i<=N;i++)p[i]=i;
for(int i=2;i<=N;i++){
if(p[i]==i){
for(int j=i;j<=N;j+=i){
p[j]=p[j]/i*(i-1);
}
}
}
for(int i=2;i<N;i++){
ans+=p[i]*2;
}
printf("%d
",ans+3);
return 0;
}
同时也看到了一种莫比乌斯环的解法,至今没搞懂
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define re register
#define debug printf("Now is Line : %d
",__LINE__)
#define file(a) freopen(#a".in","r",stdin);freopen(#a".out","w",stdout)
#define mod 1000000007
il int read()
{
re int x=0,f=1;re char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
return x*f;
}
#define maxn 40000
int mu[maxn+5],prim[maxn+5],vis[maxn+5],cnt,n,ans;
signed main()
{
n=read()-1;
if(!n) return puts("0"),0;
mu[1]=1;
for(re int i=2;i<=n;++i)
{
if(!vis[i]) prim[++cnt]=i,mu[i]=-1;
for(re int j=1;j<=cnt;++j)
{
if(prim[j]*i>n) break;
vis[prim[j]*i]=1;
if(i%prim[j]==0) break;
mu[i*prim[j]]=-mu[i];
}
}
for(re int i=1;i<=n;++i) mu[i]+=mu[i-1];
for(re int l=1,r;l<=n;l=r+1)
{
r=n/(n/l);
ans+=(mu[r]-mu[l-1])*(n/l)*(n/r);
}
printf("%d",ans+2);
return 0;
}