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+5; const int INF=0x3f3f3f3f; const int LIMIT=10000; set<int>values[15]; int C,X[15],k[15]; int Y[15][105]; void solve_enum(int S,int bc) { for(int c=0; c<C; ++c)if(c!=bc) { values[c].clear(); for(int i=0; i<k[c]; ++i) values[c].insert(Y[c][i]); } for(int t=0; S!=0; ++t) { for(int i=0; i<k[bc]; ++i) { LL n=(LL)X[bc]*t+Y[bc][i]; if(n==0)continue; bool ok=true; for(int c=0; c<C; ++c)if(c!=bc) if(!values[c].count(n%X[c])) { ok=false; break; } if(ok) { printf("%lld ",n); if(--S==0)break; } } } } int a[15]; vector<LL>sol; void exgcd(LL a,LL b,LL &d,LL& x,LL& y) { if(!b) { d=a; x=1; y=0; } else { exgcd(b,a%b,d,y,x); y-=x*(a/b); } } LL china(int n,int* a,int *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]; 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=0; i<k[dep]; ++i) { a[dep]=Y[dep][i]; dfs(dep+1); } } void solve_china(int S) { sol.clear(); dfs(0); sort(sol.begin(),sol.end()); LL M=1; for(int i=0; i<C; ++i)M*=X[i]; for(int i=0; S!=0; ++i) { for(int j=0; j<sol.size(); ++j) { LL n=M*i+sol[j]; if(n>0) { printf("%lld ",n); if(--S==0)break; } } } } int main() { int S; while(scanf("%d%d",&C,&S)==2&&C) { LL tot=1; int bestc=0; for(int c=0; c<C; ++c) { scanf("%d%d",&X[c],&k[c]); tot*=k[c]; for(int i=0; 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(" "); } return 0; }