UVA 11754 Code Feat Chinese remainder theorem + enumeration

 Code FeatUVA - 11754 

The meaning of problems: given a prime to each other c X I , for each X I , gives a ki Y J , Q s before a satisfying ans% X ans I results in Y J has occurred in.

A look that is a Chinese remainder theorem, but there is congruence equation k i product combinations, and k i the product of the maximum is 1e18, direct Chinese remainder theorem is certainly not the only pair k i product of slightly less time to use.

When k i when the product is large, it is explained for each the X- i it's the y- J are a lot, so we picked one set of the X- i , set the TEMP = * the X-ANS i + the y- J, the TEMP do not need to enumerate able to meet other large X% I = Y J ,

As for the group of the X- i selected, because we are faster to enumerate all is the y- J as much as possible, the X- i as large as possible, that is, k i / the X- i minimum.

Finally, note that the output format, the output of blank lines.

  1 #include<cstdio>
  2 #include<set>
  3 using namespace std;
  4 typedef long long ll;
  5 const int N=15;
  6 int n,m;
  7 ll bb[N],cc[N],cp;
  8 set<ll> ss[N];
  9 ll exgcd(ll a,ll b, ll &x,ll &y){
 10     if(!b){
 11         x=1;
 12         y=0;
 13         return a;
 14     }
 15     ll g=exgcd(b,a%b,y,x);
 16     y-=a/b*x;
 17     return g;
 18 }
 19 ll inv(ll a,ll c){
 20     ll g,x,y;
 21     g=exgcd(a,c,x,y);
 22     return g==1 ? (x%c+c)%c : -1;
 23 }
 24 ll crt(){
 25     ll ans=0,temp;
 26     for(int i=0;i<n;i++){
 27         temp=cp/cc[i];
 28         ans+=bb[i]*temp*inv(temp,cc[i]);
 29         if(ans>=cp) ans%=cp;
 30     }
 31     ans=(ans+cp)%cp;
 32     if(!ans) ans+=cp;
 33     return ans;
 34 }
 35 void dfs(int x){
 36     if(x==n){
 37         ss[n].insert(crt());
 38         return ;
 39     }
 40     for(set<ll>::iterator it=ss[x].begin();it!=ss[x].end();it++){
 41         bb[x]=*it;
 42         dfs(x+1);
 43     }
 44 }
 45 void solve1(){
 46     cp=1;
 47     for(int i=0;i<n;i++) cp*=cc[i];
 48     ss[n].clear();
 49     dfs(0);
 50     ll temp=0,ans;
 51     while(m){
 52         for(set<ll>::iterator it=ss[n].begin();it!=ss[n].end();it++){
 53             ans=(*it)+temp*cp;
 54             printf("%lld\n",ans);
 55             m--;
 56             if(!m) break; 
 57         }
 58         temp++;
 59     }
 60 }
 61 void solve2(int p){
 62     ll temp=0,ans;
 63     while(m){
 64         for(set<ll>::iterator it=ss[p].begin();it!=ss[p].end();it++){
 65             ans=temp*cc[p]+(*it);
 66             if(!ans) continue;
 67             bool flag=true;
 68             for(int i=0;i<n;i++){
 69                 if(i==p) continue;
 70                 if(ss[i].find(ans%cc[i])==ss[i].end()){
 71                     flag=false;
 72                     break;
 73                 }
 74             }
 75             if(flag){
 76                 printf("%lld\n",ans);
 77                 m--;
 78             }
 79             if(!m) break;
 80         }
 81         temp++;
 82     }
 83 }
 84 int main(){
 85     int k,p;
 86     ll ji,x;
 87     int t=0;
 88     while(~scanf("%d%d",&n,&m)){
 89         if(t) printf("\n");
 90         t=1; 
 91         p=-1;ji=1;
 92         for(int i=0;i<n;i++){
 93             ss[i].clear();
 94             scanf("%lld",&cc[i]);
 95             scanf("%d",&k);
 96             ji*=k;
 97             if(p==-1||k*cc[p]<(int)ss[p].size()*cc[i]) p=i;
 98             while(k--){
 99                 scanf("%lld",&x);
100                 ss[i].insert(x); 
101             }
102         }
103         if(ji<=10000) solve1();
104         else solve2(p);
105     }
106     return 0;
107 }
Ingenious classification solve

 

Guess you like

Origin www.cnblogs.com/LMCC1108/p/11689671.html