zoukankan      html  css  js  c++  java
  • UVA 11754 Code Feat 中国剩余定理+枚举

     Code FeatUVA - 11754 

    题意:给出c个彼此互质的xi,对于每个xi,给出ki个yj,问前s个ans满足ans%xi的结果在yj中有出现过。

    一看便是个中国剩余定理,但是同余方程组就有ki的乘积种组合,而ki的乘积最大是1e18,直接中国剩余定理肯定不是的,只能对ki的乘积稍微小的时候才能使用。

    而当ki的乘积很大时,便说明对于每个xi它的yj都很多,那么我们挑选其中一组xi,设ans=temp*xi+yj,temp不需要枚举到很大便能满足其他的%xi=yj,

    至于那组xi的选择,因为我们是要枚举得更快,所有便是yj尽可能的多,xi尽可能的大,也就是ki/xi最小。

    最后注意输出格式上,空行的输出。

      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
    ",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
    ",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("
    ");
     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 }
    巧妙的分类解决
  • 相关阅读:
    python 基础2.5 循环中continue与breake用法
    python 基础 2.4 while 循环
    python 基础 2.3 for 循环
    python 基础 2.2 if流程控制(二)
    python 基础 2.1 if 流程控制(一)
    python 基础 1.6 python 帮助信息及数据类型间相互转换
    python 基础 1.5 python数据类型(四)--字典常用方法示例
    Tornado Web 框架
    LinkCode 第k个排列
    LeetCode 46. Permutations
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/11689671.html
Copyright © 2011-2022 走看看