CF1010C

题目链接

题目描述

\(\left( a_{1}x_{1}+a_{2}x_{2}+\ldots +a_{n}x_{n}\right) \% k\) 的值情况数.
(ai,xi均为非负整数)

输入输出格式

输入格式:

第一行两个整数n,k
第二行n个整数a1...an
(1<=n,k<=100000)
(1<=ai<=1e9)

输出格式:

第一行输出一个整数,表示情况数
第二行升序输出一个序列,表示可能出现的值

样例

输入样例 输出样例
2 8 12 20 2 0 4
3 10 10 20 30 1 0

思路

1.数论

设d=\(\left( a_{1}x_{1}+a_{2}x_{2}+\ldots +a_{n}x_{n}\right) \% k\)
则d=$ a_{1}x_{1}+a_{2}x_{2}+\ldots +a_{n}x_{n}-ky$ (y为非负整数)
又因为在ai,xi为整数的情况下d的值只可能为$ \gcd \left( a_{1}\ldots a_{n},k\right) $ 的倍数
所以先计算$ \gcd \left( a_{1}\ldots a_{n},k\right) $
然后计算结果就可以了
证明请见欧几里得算法与扩欧

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <set>
#include <map>
#define ll long long
#define ull unsigned long long
#define ci const int&
#define cl const long long&
#define cul const undigned long long&
#define io_f std::ios::sync_with_stdio(false)
using namespace std;

int n,k;

int gcd(ci x,ci y) {return y==0?x:gcd(y,x%y);}

int main() {
	io_f;
	int a,x;
	cin>>n>>k;
	x=k;
	for(int i=1;i<=n;i++) {
		cin>>a;
		x=gcd(x,a);
	}
	cout<<k/x<<endl;
	for(int i=0;i<k;i+=x) cout<<i<<endl;

	return 0;
}
posted @ 2018-07-31 02:06  ullio  阅读(234)  评论(0编辑  收藏  举报