Problem - B - Codeforces
Arkady和他的朋友们喜欢在一个n × n的棋盘上玩跳棋。这个棋盘的行和列从1到n编号。
他的朋友们最近赢了一场比赛,所以Actady想用一些糖果来取悦他们。记得一则古老寓言(但不记得寓意)》,Arlady想给他的朋友们每个格子一个糖果组:第(1.j)个格子的糖果组将有(+j2)种不同类型的糖果。
有m个值得获得礼物的朋友。有多少个n × n的糖果组可以被平均地分成m 部分而不切碎任何一个糖果?请注意,每个组必须独立分割,因为不同组中的糖果类型不同。
输入
仅一行包含两个整数n和m (1<n<109,1<m <1000)——场地的大小和要将组件分成的部分数。
输出
输出单个整数——可以平均分成的组数。
Examples
input
Copy
3 3
output
Copy
1
input
Copy
6 5
output
Copy
13
input
Copy
1000000000 1
output
Copy
1000000000000000000
在第一个例子中,只有单元格(3,3)的集合可以被平均分割(32+32=18,可被m=3整除)。
在第二个例子中,以下单元格的集合可以被平均分割:
(1,2)和(2,1),因为12+22=5,可以被5整除; (1,3)和(3,1); (2,4)和(4,2); (2,6)和(6,2); (3,4)和(4,3); (3,6)和(6,3); (5,5)。
在第三个例子中,所有单元格中的集合都可以被平均分割,因为m=1。
题解:
由于m只有1000,所有我们要从m着手考虑,
(i*i + j*j)%m == 0
(i%m*i%m + j%m*j%m) == 0
我们可以把n*n的块分成很多,m*m的小块,类似这样
接着我们算这四块的面积即可
#include <cstdio>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
#define int long long
typedef pair<int,int> PII;
int mod = 998244353;
int n;
int a[505];
void solve()
{
int n,m;
cin >> n >> m;
int cnt = 0;
for(int i = 1;i <= m;i++)
{
for(int j = 1;j <= m;j++)
{
int x = i*i + j*j;
if(x% m == 0)
cnt++;//m*m小块的符合答案数量
}
}
int ans = 0;
ans += (n/m)*(n/m)*cnt;//多少个m*m的小块
cnt = 0;
for(int i = n - n%m + 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
int x = i*i + j*j;
if(x%m == 0)
cnt++;左边长条的符合答案数量
}
}
ans += n/m*cnt*2;//由于有两个长块
cnt = 0;
for(int i = n - n%m + 1;i <= n;i++)
{
for(int j = n - n%m + 1;j <= n;j++)
{
int x = i*i + j *j;
if(x%m == 0)
cnt++;//右上方块的答案
}
}
cout << ans + cnt;
}
signed main()
{
// ios::sync_with_stdio(0 );
// cin.tie(0);cout.tie(0);
int t = 1;
// cin >> t;
while(t--)
{
solve();
}
}