Uva 11754(枚举+中国剩余定理)

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<queue>
  7 #include<map>
  8 #include<set>
  9 #include<vector>
 10 #include<cstdlib>
 11 #include<string>
 12 #define eps 0.000000001
 13 typedef long long ll;
 14 typedef unsigned long long LL;
 15 using namespace std;
 16 const int maxc=9;
 17 const int maxk=100;
 18 set<int>value[maxc];
 19 int C,x[maxc],k[maxc];
 20 int y[maxc][maxk];
 21 int a[maxc];
 22 ll exgcd(ll a,ll b,ll &xx,ll &yy){
 23     if(b==0){
 24         xx=1;yy=0;return a;
 25     }
 26     ll r=exgcd(b,a%b,xx,yy);
 27     ll t=yy;
 28     yy=xx-(a/b)*yy;
 29     xx=t;
 30     return r;
 31 }
 32 ll CRT(int a[],int m[],int n){//ÖйúÊ£ÓඨÀí
 33     ll M=1;
 34     ll ans=0;
 35     for(int i=0;i<n;i++)M=M*m[i];
 36     for(int i=0;i<n;i++){
 37         ll Mi=M/m[i];
 38         ll xx,yy;
 39         ll r=exgcd(Mi,(ll)m[i],xx,yy);
 40         ans=(ans+xx*a[i]*Mi)%M;
 41     }
 42     if(ans<0)ans=(ans+M)%M;
 43     return ans;
 44 }
 45 void solve_enum(int S,int bc){
 46     for(int c=0;c<C;c++)
 47     if(c!=bc){
 48         value[c].clear();
 49         for(int i=0;i<k[c];i++)value[c].insert(y[c][i]);
 50 
 51     }
 52     for(int t=0;S!=0;t++){
 53         for(int i=0;i<k[bc];i++)
 54         {
 55             ll n=(ll)x[bc]*t+y[bc][i];
 56             if(n==0)continue;
 57             bool ok=true;
 58             for(int c=0;c<C;c++)if(c!=bc)
 59             if(!value[c].count(n%x[c])){ok=false;break;}
 60             if(ok){
 61                 printf("%lld
",n);
 62                 if(--S==0)break;
 63             }
 64         }
 65     }
 66 }
 67 vector<ll>sol;
 68 void dfs(int dep){
 69     if(dep==C)sol.push_back(CRT(a,x,C));
 70     else{
 71         for(int i=0;i<k[dep];i++){
 72             a[dep]=y[dep][i];
 73             dfs(dep+1);
 74         }
 75     }
 76 }
 77 void solve_china(int S){
 78     sol.clear();
 79     dfs(0);
 80     sort(sol.begin(),sol.end());
 81     ll M=1;
 82     for(int i=0;i<C;i++)M=M*x[i];
 83     vector<ll>ans;
 84     for(int i=0;S!=0;i++){
 85         for(int j=0;j<sol.size();j++){
 86             ll n=M*i+sol[j];
 87             if(n>0){
 88                 printf("%lld
",n);
 89                 if(--S==0)break;
 90             }
 91         }
 92     }
 93 }
 94 int main(){
 95     int S;
 96     while(scanf("%d%d",&C,&S)!=EOF){
 97         if(C==0&&S==0)break;
 98         ll tot=1;
 99         int bestc=0;
100         for(int c=0;c<C;c++){
101             scanf("%d%d",&x[c],&k[c]);
102             tot=tot*k[c];
103             for(int i=0;i<k[c];i++)scanf("%d",&y[c][i]);
104             sort(y[c],y[c]+k[c]);
105             if(k[c]*x[bestc]<k[bestc]*x[c])bestc=c;
106         }
107         if(tot>10000)solve_enum(S,bestc);
108         else{
109                // cout<<1<<endl;
110             solve_china(S);
111         }
112         cout<<endl;
113     }
114 }
原文地址:https://www.cnblogs.com/Aa1039510121/p/6291362.html