题目:https://uva.onlinejudge.org/external/117/11754.pdf
中国剩余定理和拓展欧几里德感觉还没弄清楚,只能套模板。
这题这是照着书上的代码写的:
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI 3.1415926535897932384626
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)
#define lson num<<1,le,mid
#define rson num<<1|1,mid+1,ri
#define MID int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
using namespace std;
//const int INF= ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxc= 9 ;
const int maxk= 100;
const int LIMIT=10000;
set<int >value[maxc];
int C,X[maxc],k[maxc];
int Y[maxc][maxk];
int S;
//const int maxm= ;
//by yskysker123
void Work(int bestc)
{
for(int i=0;i<C;i++)
{
if(i==bestc) continue;
value[i].clear();//掉了
for(int j=0;j<k[i];j++)
{
value[i].insert(Y[i][j]);
}
}
for(int t=0 ;S ;t++ )
{
for(int j=0;j<k[bestc];j++)
{
ll n=(ll)t*X[bestc]+Y[bestc][j];//
if(!n) continue ;//n不能为0
bool ok=true;
for(int i=0;i<C;i++)
{
if(i==bestc) continue;
if(!value[i].count(n%X[i]))
{
ok=false;
break;
}
}
if(ok) {printf("%lld\n",n);if(!(--S)) break; }
}
}
}
vector<ll> sol;
int a[maxc];
void gcd(ll a, ll b, ll d, ll& x, ll& y) {
if(!b){ d = a; x = 1; y = 0; }
else{ gcd(b, a%b, d, y, x); y -= x*(a/b); }
}
ll China(int n,int *a,int *m)//方程个数,余数,模m
{
ll M=1,d,y,x=0;
for(int i=0;i<n;i++) M*=m[i];
for(int i=0;i<n;i++)
{
ll w=M/m[i];
gcd(m[i] ,w,1,d,y);
x=(x+w*y*a[i])%M;
}
return (x+M)%M;
}
void dfs(int step)
{
if(step==C)
{sol.push_back(China( C ,a,X)) ;return;}// ,余数(数组),模X(数组)
for(int i=0;i<k[step];i++)
{
a[step]=Y[step][i];
dfs(step+1);
}
}
void Solve_China()
{
sol.clear();
dfs(0);
ll M=1;
for(int i=0;i<C;i++)
M*=X[i];
sort(sol.begin(),sol.end());
for(int t=0;S;t++)
{
for(int i=0;i<sol.size();i++)
{
ll n=t*M+sol[i];
if(!n) continue;
printf("%lld\n",n);
if( !(--S ) ) break;
}
}
}
int main()
{
while(scanf("%d%d",&C,&S)==2&&(C||S))
{
ll tot=1;int bestc=0;
for(int i=0;i<C;i++)
{
scanf("%d%d",&X[i],&k[i]);
tot*=k[i];
for(int j=0;j<k[i];j++)
{
scanf("%d",&Y[i][j]);
}
if( X[bestc]*k[i]<k[bestc]*X[i] ) bestc=i;
sort(Y[i],Y[i]+k[i]);//掉了,不能保证最小
}
if(tot>LIMIT) Work(bestc);
else Solve_China();
putchar('\n');
}
return 0;
}