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

 

posted @ 2018-08-26 20:08  qwerity  阅读(190)  评论(0编辑  收藏  举报