题目链接:CF
题意:给出n,让你找出 (x*x+y*y)%m==0的点对(0<x<=n,0<y<=n),问有多少对。
参考官方题解:(x*x+y*y)%m==0,等价于 ((x%m)^2+(y%m)^2)%m==0,设i=x%m,j=y%m,即坐标范围n*n内满足的点对(x,y),其模值对 (i,j)一定在范围 m*m中,故我们可以直接暴力 m*m,然后我们看看在n*n范围内包含多少块m*m,最后处理下多出来的就行了。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
LL n;
int m;
LL Count(int x1,int x2,int y1,int y2)
{
LL sum=0;
for(int i=x1;i<=x2;i++)
{
for(int j=y1;j<=y2;j++){
if((i*i+j*j)%m==0){
sum++;
}
}
}
return sum;
}
int main()
{
while(~scanf("%lld%d",&n,&m))
{
LL sum=0;
LL item=Count(1,m,1,m); ///首先计算m*m满足条件的有多少个
sum=sum+item*(n/(LL)m)*(n/(LL)m); ///先计算S
if(n%m==0){
printf("%lld\n",sum);continue;
}
item=Count(1,m,1,n%m); ///m*(n%m) ///计算S1
sum+=item*(n/(LL)m);
item=Count(1,n%m,1,m); ///计算S2
sum+=item*(n/(LL)m);
sum+=Count(1,n%m,1,n%m); ///计算S3
printf("%lld\n",sum);
}
return 0;
}