求复合(鸽巢定理应用)
Posted 佐鼬Jun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求复合(鸽巢定理应用)相关的知识,希望对你有一定的参考价值。
求复合
Description
小啵的女朋友非常喜欢数字,而小啵的女朋友在和他在闹分手。他拥有n个数字,今天他又获得了一个数字m,小啵需要利用这n个数和数字m求出一个神奇的数ans = ∏1≤i<j≤n|ai−aj|=|a1−a2|⋅|a1−a3|⋅…… ⋅|a1−an|⋅|a2−a3|⋅|a2−a4|⋅…… ⋅|a2−an|⋅…… ⋅|an−1−an|
Input
第一行输入两个数字,n, m;(2≤n≤200000, 1≤m≤1000);
第二行输入n个数字,a1, a2, a3, …, an;(0≤ai≤1e9);
Output
一个单独的数字, ∏1≤i<j≤n|ai − aj| mod m;
Sample
Input
2 10
8 5
Output
3
Hint
∏1≤i<j≤n|ai−aj|=|a1−a2|⋅|a1−a3|⋅…… ⋅|a1−an|⋅|a2−a3|⋅|a2−a4|⋅…… ⋅|a2−an|⋅…… ⋅|an−1−an|
思路: 对于
n
<
=
m
n<=m
n<=m,直接两层循环暴力求值即可
对于
n
>
m
n>m
n>m的情况,一定是
0
0
0.
证明: 考虑最坏的情况,对于m个数来说,这m个数取余m,值为0,1,2,…m-1。那还剩下n-m个数,这n-m个数,取余m,也一定在[0,m-1]范围内,所以至少有两个数同模的(取余后模数相同),由于模数相同的两数相减后取余一定是0,所以最后的值一定是0.
证明两个同模的数,相减后取模一定为0
设第一个数为
a
+
a+
a+
k
1
k_1
k1m,由于第二个数和第一个数同模,所以设为
a
+
a+
a+
k
2
k_2
k2m,这两个数相减后为(
k
1
k_1
k1-
k
2
k_2
k2)
∗
m
*m
∗m,取绝对值后,是m的倍数,取模后,一定为0.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=200010;
int a[N];
int main() {
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) {
scanf("%lld",&a[i]);
}
if(n>m) puts("0");
else {
ll ans=1;
for(int i=1;i<=n;i++) {
for(int j=i+1;j<=n;j++) {
ans=ans*abs(a[i]-a[j])%m;
}
}
printf("%d\\n",ans);
}
return 0;
}
To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激
以上是关于求复合(鸽巢定理应用)的主要内容,如果未能解决你的问题,请参考以下文章