lrj白书例题,真好
#include <stdio.h>
#include <iostream>
#include <vector>
#include <math.h>
#include <set>
#include <queue>
#include <algorithm>
#include <string.h>
#include <string>
using namespace std;
typedef long long LL;
const int N=1e2+;
const int INF=0x3f3f3f3f;
const int LIMIT=;
set<int>values[];
int C,X[],k[];
int Y[][];
void solve_enum(int S,int bc)
{
for(int c=; c<C; ++c)if(c!=bc)
{
values[c].clear();
for(int i=; i<k[c]; ++i)
values[c].insert(Y[c][i]);
}
for(int t=; S!=; ++t)
{
for(int i=; i<k[bc]; ++i)
{
LL n=(LL)X[bc]*t+Y[bc][i];
if(n==)continue;
bool ok=true;
for(int c=; c<C; ++c)if(c!=bc)
if(!values[c].count(n%X[c]))
{
ok=false;
break;
}
if(ok)
{
printf("%lld\n",n);
if(--S==)break;
}
}
}
}
int a[];
vector<LL>sol;
void exgcd(LL a,LL b,LL &d,LL& x,LL& y)
{
if(!b)
{
d=a;
x=;
y=;
}
else
{
exgcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
LL china(int n,int* a,int *m)
{
LL M=,d,y,x=;
for(int i=; i<n; ++i)M*=m[i];
for(int i=; i<n; ++i)
{
LL w=M/m[i];
exgcd(m[i],w,d,d,y);
x=(x+y*w*a[i])%M;
}
return (x+M)%M;
}
void dfs(int dep)
{
if(dep==C)sol.push_back(china(C,a,X));
else for(int i=; i<k[dep]; ++i)
{
a[dep]=Y[dep][i];
dfs(dep+);
}
}
void solve_china(int S)
{
sol.clear();
dfs();
sort(sol.begin(),sol.end());
LL M=;
for(int i=; i<C; ++i)M*=X[i];
for(int i=; S!=; ++i)
{
for(int j=; j<sol.size(); ++j)
{
LL n=M*i+sol[j];
if(n>)
{
printf("%lld\n",n);
if(--S==)break;
}
}
}
}
int main()
{
int S;
while(scanf("%d%d",&C,&S)==&&C)
{
LL tot=;
int bestc=;
for(int c=; c<C; ++c)
{
scanf("%d%d",&X[c],&k[c]);
tot*=k[c];
for(int i=; i<k[c]; ++i)scanf("%d",&Y[c][i]);
sort(Y[c],Y[c]+k[c]);
if(k[c]*X[bestc]<k[bestc]*X[c])bestc=c;
}
if(tot>LIMIT)solve_enum(S,bestc);
else solve_china(S);
printf("\n");
}
return ;
}