To become the king of Codeforces, Kuroni has to solve the following problem.
He is given nn numbers a1,a2,…,ana1,a2,…,an. Help Kuroni to calculate ∏1≤i<j≤n|ai−aj|. As result can be very big, output it modulo mm.
If you are not familiar with short notation, ∏1≤i<j≤n|ai−aj| is equal to |a1−a2|⋅|a1−a3|⋅|a1−a2|⋅|a1−a3|⋅ …… ⋅|a1−an|⋅|a2−a3|⋅|a2−a4|⋅⋅|a1−an|⋅|a2−a3|⋅|a2−a4|⋅ …… ⋅|a2−an|⋅⋅|a2−an|⋅ …… ⋅|an−1−an|⋅|an−1−an|. In other words, this is the product of |ai−aj||ai−aj| for all 1≤i<j≤n1≤i<j≤n.
Input
The first line contains two integers nn, mm (2≤n≤2⋅1052≤n≤2⋅105, 1≤m≤10001≤m≤1000) — number of numbers and modulo.
The second line contains nn integers a1,a2,…,ana1,a2,…,an (0≤ai≤1090≤ai≤109).
Output
Output the single number — ∏1≤i<j≤n|ai−aj|modm∏1≤i<j≤n|ai−aj|modm.
input
2 10
8 5
output
3
题目要求:求每一个满足1≤i<j≤n的|ai−aj|的乘积,输出这个乘积对m的模。
如果暴力求解,面对200000个数字的测试用例肯定会超时,所以我们需要用一点数学技巧进行简单的判断。
由于每个数字互不相同,那么当数字的数量n大于模数m时,一定会有两个数字的差恰好等于m,使得这两个数的差(等于m)乘上其他数字对m的模恒等于0,那么我们就可以肯定这种情况下最终的结果为0。
例如:对于1、2、3、4这四个数字,求∏1≤i<j≤n|ai−aj|对3的模,那么一定有4-1对3的模为0,即使乘上其他数字后再求对3的模也依然为0。
当n小于等于m的时候,最终求模的结果是否为零无法判断,所以我们用两层for循环进行计算。每次计算后都直接对结果求模,使sum的值变小,否则sum的值会过大而导致溢出。
这种情况下,由于m最大也就是999,使得我们只需要在n小于1000的时候才进行计算,这比暴力求解的200000个数字小了很多,不至于超时。
#include <stdio.h>
#include <math.h>
int a[200000];
int main(void)
{
int i, t, n, m;
unsigned long long sum = 1;
scanf("%d%d", &n, &m);
if (n > m)
sum = 0;
else
{
for (t = 0; t < n; t++)
{
scanf("%d", &a[t]);
}
for (t = 0; t < n; t++)
{
if (sum == 0)
break;
for (i = t + 1; i < n; i++)
{
sum *= abs(a[t] - a[i]) % m;
sum %= m;
}
}
}
printf("%d", sum);
return 0;
}