求复合(鸽巢定理应用)

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
如果你有任何建议或者批评和补充,请留言指出,不胜感激

以上是关于求复合(鸽巢定理应用)的主要内容,如果未能解决你的问题,请参考以下文章

poj2356Find a multiple——鸽巢定理运用

鸽巢定理(21.9.26)

浅谈鸽巢原理的证明和简单应用

7.25 鸽巢原理,中国剩余定理,欧拉函数

9.高等数学-导数

第五关——数论:组合数学