Codeforces #499 E Border ( 裴蜀定理 )

Posted rubbishes

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces #499 E Border ( 裴蜀定理 )相关的知识,希望对你有一定的参考价值。

题目链接

题意 : 给出 N 种纸币、并且给出面值、每种纸币的数量可以任选、问你得出来的数在 k 进制下、末尾位的数有多少种可能、输出具体方案

 

分析 :

纸币任意选择组成的和

可以用一个一次多项式来表示

A1*B1 + A2*B2 + A3*B3 + ... + An*Bn ( A 为面值、B 为数量 )

根据裴蜀定理、这个一次多项式的结果集应当是 gcd( A1、A2 .... An ) 的倍数

然后考虑怎么得到每个数 k 进制下的最后一位数

实际上你考虑一下十进制是怎么转化为 k 进制的

就能够分析出、只要将这个十进制模以 k 就能得到

那么也就是说要求 ( A1*B1 + A2*B2 + A3*B3 + ... + An*Bn ) % k 的结果集

模可以转化为减法 故有 A1*B1 + A2*B2 + A3*B3 + ... + An*Bn - y*k

那么结果集就应当是 gcd( A1、A2 .... An 、k ) 的倍数

那么总数就有 k / gcd( A1、A2 .... An 、k )

具体的方案就直接枚举 gcd 的倍数就行了、上界为 k

 

技术分享图片
#include<bits/stdc++.h>
using namespace std;

int main(void)
{
    int n, k;
    cin>>n>>k;

    int GCD = -1;
    for(int i=1; i<=n; i++){
        int tmp;
        cin>>tmp;
        if(GCD == -1) GCD = tmp;
        else GCD = __gcd(GCD, tmp);
    }

    GCD = __gcd(GCD, k);

    cout<< k / GCD <<endl;

    for(int i=0; i<k; i+=GCD) cout<<i<<" "; cout<<endl;

    return 0;
}
View Code

 

以上是关于Codeforces #499 E Border ( 裴蜀定理 )的主要内容,如果未能解决你的问题,请参考以下文章

[codeforces/gym/100431/E]KMP关于border的理解

[Codeforces 1011E] Border

CodeForces 499D. Name That Tune(概率dp)

7-27 Codeforces Round #499 (Div. 2)

codeforces round #499(div2) 做题记录

网络流(最大流):CodeForces 499E Array and Operations