题目链接:http://codeforces.com/problemset/problem/1010/C
题目大意:给定n个数Ai,一个整数k,每个数可以用任意次,求这些数的和模K之后有多少种可能,分别是哪些数。

思路:从简到繁

(1)当存在某个Ai模K等于1时,那答案是K,从0到K-1都可以;

(2)当n个数模K都不是1,如果存在Ai % K = x,Ai % K = y,gcd(x,y) = 1,那么根据数论性质,由x和y可以构造出0 - K-1的任意数:x,x+y,x+2y,……,x+(k-1)y这些数在同余的意义下就是 0 - K-1

(3)若不存在(1)(2)中的情况,那么就是所有的Ai % K之后,再取上gcd,会等于一个数X,可知X是K的约数(可以利用反证,若gcd(X,K)=1,那么X,2X,3X,……,(K-1)X在同余意义下就是0 - K-1,和(2)相同了),那么结果为K/X

总结:求k和给定的数组的gcd。能够组成的数的个数为:k/gcd。

#include<bits/stdc++.h>
#define LL long long
using namespace std;

vector<int> v;
int main()
{
    int n, k, a;
    scanf("%d%d", &n, &k);
    int gcd=k;
    for(int i=1; i<=n; i++){
        scanf("%d", &a);
        gcd=__gcd(gcd, a);
    }
    printf("%d\n", k/gcd);
    for(int i=gcd; i<=k; i+=gcd){
        v.push_back(i%k);
    }
    sort(v.begin(), v.end());
    for(int i=0; i<v.size(); i++){
        printf("%d%c", v[i], i==v.size()-1?'\n':' ');
    }

	return 0;
}