B. Divide Candies(数学 + 思维)

Problem - B - Codeforces

B. Divide Candies(数学 + 思维)_第1张图片

Arkady和他的朋友们喜欢在一个n × n的棋盘上玩跳棋。这个棋盘的行和列从1到n编号。
他的朋友们最近赢了一场比赛,所以Actady想用一些糖果来取悦他们。记得一则古老寓言(但不记得寓意)》,Arlady想给他的朋友们每个格子一个糖果组:第(1.j)个格子的糖果组将有(+j2)种不同类型的糖果。
有m个值得获得礼物的朋友。有多少个n × n的糖果组可以被平均地分成m 部分而不切碎任何一个糖果?请注意,每个组必须独立分割,因为不同组中的糖果类型不同。
输入
仅一行包含两个整数n和m (1 输出
输出单个整数——可以平均分成的组数。

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的小块,类似这样

B. Divide Candies(数学 + 思维)_第2张图片

接着我们算这四块的面积即可 

 

#include 
#include 
#include 
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define int long long
typedef pair 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(); 
	}
}

你可能感兴趣的:(算法)