Problem - E - Codeforces
太空人纳塔莎抵达了火星。她知道火星人非常贫穷。为了保障火星公民更好的生活,他们的皇帝决定向每个游客征收税费。纳塔莎是地球的居民,因此她必须支付进入火星领土所需的税费。
火星上有n种纸币面额:第i种纸币的面额为ai。纳塔莎拥有每种面额的无限张纸币。
火星人手指有k个,因此他们使用基于k的数字系统。此外,火星人认为数字d(在基于k的数字系统中)是神圣的。因此,如果纳塔莎在以基于k的数字系统表示的税款金额的最后一位是数字d,则火星人会感到高兴。不幸的是,纳塔莎目前不知道火星人的神圣数字。
确定哪些值d可以使纳塔莎让火星人高兴。
纳塔莎只能使用自己的纸币。火星人不会找零。
输入格式 第一行包含两个整数n和k(1≤n≤100000,2≤k≤100000)——纸币面额数量和火星上的数字系统基数。
第二行包含n个整数a1,a2,…,an(1≤ai≤109)——火星上纸币的面额。
输出格式 第一行输出可以让火星人高兴的d值的数量。
第二行按升序输出所有这些数字。
以十进制形式打印所有数字。
Examples
Input
Copy
2 8 12 20
Output
Copy
2 0 4
Input
Copy
3 10 10 20 30
Output
Copy
1 0
考虑第一个测试用例,它使用八进制数字系统。
如果你拿了一张面额为12的纸币,你会得到148(八进制下)的金额。最后一位是8。
如果你同时拿了一张面额为12和一张面额为20的纸币,总金额将会是32。在八进制下,它是408。最后一位是8。
如果你拿了两张面额为20的纸币,总金额将会是40,在八进制下是508。最后一位是8。
没有其他除了08和48以外的数值可以获得。而08和48这两个数字也可以通过其他方式获得。
第二个测试用例使用十进制数字系统。所有纸币面额的末尾都是0,所以纳塔莎只能给火星人以十进制表示也以0结尾的金额。
题解:
可以构成的总钱数可以这样表达
c = b1*a1 + b2*a2 + b3*a3 + ... bn*an
数组b代表每一个种类的钱取多少张
根据裴蜀定理
定理:
裴蜀定理(或贝祖定理,Bézout's identity)得名于法国数学家艾蒂安·裴蜀,说明了对任何整数a、b和它们的最大公约数d,关于未知数x和y的线性不定方程(称为裴蜀等式):若a,b是整数,且GCD(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立。
我们知道g = gcd(a1,a2,...an)
c一定是g的倍数
题中问总钱数%k的有多少种
(b1*a1 + b2*a2 + b3*a3 + ... bn*an )%k
%k的操作又可以用减法来代替,
b1*a1 + b2*a2 + b3*a3 + ... bn*an - y*k
那么答案就变成了 g = gcd(g,k)的倍数
枚举0 ~ k - 1即可
#include <cstdio>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
#define int long long
typedef pair<int,int> PII;
typedef unsigned long long ULL;
const int N = 3e5 + 10;
int mod = 1e9 + 7;
void solve()
{
int n,k;
cin >> n >> k;
int g = k;
for(int i = 1;i <= n;i++)
{
int x;
cin >> x;
g = __gcd(g,x);
}
cout << k/g <<"\n";
for(int i = 0;i < k;i += g)
cout <<i <<" ";
}
signed main()
{
ios::sync_with_stdio(0 );
cin.tie(0);cout.tie(0);
int t = 1;
// cin >> t;
while(t--)
{
solve();
}
}