• Root(hdu5777+扩展欧几里得+原根)2015 Multi-University Training Contest 7


    Root

    Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
    Total Submission(s): 34    Accepted Submission(s): 6


    Problem Description
    Given a number sum(1sum100000000),we have m queries which contains a pair (xi,yi) and would like to know the smallest nonnegative integer kisatisfying xkii=yi mod p when the prime number p (sum mod p=0)(ps:00=1)
     
    Input
    The first line contains a number T, indicating the number of test cases. 

    For each case, each case contains two integers sum,m(1sum100000000,1m100000) in the first line. 

    The next m lines will contains two intgeers xi,yi(0xi,yi1000000000)
     
    Output
    For each test case,output "Case #X:" and m lines.(X is the case number) 

    Each line cotain a integer which is the smallest integer for (xi,yi) ,if we can't find such a integer just output "-1" without quote.
     
    Sample Input
    1
    175 2
    2 1
    2 3
     
    Sample Output
    Case #1:
    0
    3
    Hint
     
    175 =5^27
    2^0 mod 5 = 1
    2^3 mod 7 = 1
    So the answer to (2,1) is 0
     
    Source
     
     
     
    比较经典一道扩展欧几里得 



    现在,我们首先来解决下原根的问题:简单的解释可以参考:>>原根<<  

     资源下载:http://download.csdn.net/detail/u010579068/8993383

    不急看懂的,可以先去切道 定义题    链接:1135 原根  

    解题 http://www.cnblogs.com/yuyixingkong/p/4722821.html

    转载请注明出处:寻找&星空の孩子     

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5377

     
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<map>
      7 using namespace std;
      8 typedef long long ll;
      9 const int maxn=1e6+1;
     10 const int maxv=1e5+1;
     11 bool isnp[maxv];
     12 int prime[maxv],pnum;//素数数组,素数个数
     13 int cas;
     14 void get_prime()//素数打表
     15 {
     16     pnum=0;
     17     int i,j;
     18     memset(isnp,0,sizeof(isnp));
     19     isnp[0]=isnp[1]=true;
     20     for(i=2; i<maxv; i++)
     21     {
     22         if(!isnp[i])prime[pnum++]=i;
     23         for(j=0; j<pnum&&prime[j]*i<maxv; j++)
     24         {
     25             isnp[i*prime[j]]=true;
     26             if(i%prime[j]==0)break;
     27         }
     28     }
     29 }
     30 ll qukpow(ll k,ll base,ll p)
     31 {
     32     ll res=1;
     33     for(; k; k>>=1)
     34     {
     35         if(k&1)res=(res*base)%p;
     36         base=(base*base)%p;
     37     }
     38     return res;
     39 }
     40 ll ppow(ll a,ll b,ll mod)
     41 {
     42     ll c=1;
     43     while(b)
     44     {
     45         if(b&1) c=c*a%mod;
     46         b>>=1;
     47         a=a*a%mod;
     48     }
     49     return c;
     50 }
     51 ll fpr[maxv];
     52 
     53 ll find_primitive_root(ll p)//求p的原根    g^(p-1) = 1 (mod p); 求g
     54 {
     55     ll cnt=0,num=p-1,res;
     56     int i;
     57     if(p==2)return 1;
     58     for(i=0; i<pnum && prime[i]*prime[i]<=num && num>1 ; i++)
     59     {
     60         if(num%prime[i]==0)//
     61         {
     62             fpr[cnt++]=prime[i];
     63             while(num%prime[i]==0)num/=prime[i];
     64         }
     65     }
     66     if(num>1)fpr[cnt++]=num;//fpr[]存的是p-1的因子
     67     for(res=2; res<=p-1; res++)//暴力
     68     {
     69         for(i=0; i<cnt; i++)
     70             if(ppow(res,p/prime[i],p)==1)break;
     71         if(i>=cnt)return res;
     72     }
     73     return -1;
     74 };
     75 
     76 const int mod=1e6+7;
     77 
     78 struct solve
     79 {
     80     struct HashTable
     81     {
     82         int top,head[mod];
     83         struct Node
     84         {
     85             int x,y,next;
     86         } node[mod];
     87         void init()
     88         {
     89             top=0;
     90             memset(head,0,sizeof(head));
     91         }
     92         void insert(ll x,ll y)
     93         {
     94             node[top].x=x;
     95             node[top].y=y;
     96             node[top].next=head[x%mod];
     97             head[x%mod]=top++;
     98         }
     99         ll query(ll x)
    100         {
    101             for(int tx=head[x%mod]; tx; tx=node[tx].next)
    102                 if(node[tx].x==x)return node[tx].y;
    103             return -1;
    104         }
    105     } mp;
    106 
    107     ll p;
    108     ll discretelog(ll prt,ll a) //取对数
    109     {
    110         ll res,am=ppow(prt,maxn-1,p),inv=ppow(a,p-2,p),x=1;
    111         for(ll i=maxn-1;; i+=(maxn-1))
    112         {
    113             if((res=mp.query((x=x*am%p)*inv%p))!=-1)
    114             {
    115                 
    116                 return i-res;
    117             }
    118             if(i>p)break;
    119         }
    120         return -1;
    121     }
    122     void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y)//扩展欧几里得 x为最后需要的k
    123     {
    124         if(!b)
    125         {
    126             d=a;
    127             x=1;
    128             y=0;
    129         }
    130         else
    131         {
    132             ex_gcd(b,a%b,d,y,x);
    133             y-=x*(a/b);
    134         }
    135     }
    136 
    137     ll proot;
    138     void init()
    139     {
    140         mp.init();
    141         ll tmp,x,y,d;
    142         int i;
    143         proot=find_primitive_root(p);//找到素数p的原根
    144         for(i=0,tmp=1; i<maxn-1; i++,tmp=tmp*proot%p)
    145             mp.insert(tmp%p,i*1ll);
    146     }
    147     ll query(ll x,ll y)
    148     {
    149         ll d;
    150         x%=p;
    151         y%=p;
    152         
    153         if(y==1)return 0;
    154         else if(x==0)
    155         {
    156             if(y==0)return 1;
    157             else return -1;
    158         }
    159         else if(y==0)return -1;
    160         else
    161         {
    162             ll s=discretelog(proot,x);
    163             
    164             ll t=discretelog(proot,y);
    165             
    166             ex_gcd(s,p-1,d,x,y);
    167             if(t%d)return -1;
    168             else
    169             {
    170                 ll dx=(p-1)/d;
    171                 x=(x%dx+dx)%dx;
    172                 x*=(t/d);
    173                 x=(x%dx+dx)%dx;
    174                 return x;
    175             }
    176         }
    177     }
    178 } sol[32];
    179 int main()
    180 {
    181     int i,j,q,con,T;
    182     ll sum,x,y;
    183     scanf("%d",&T);
    184     get_prime();
    185     cas=1;
    186     while(cas<=T)
    187     {
    188         con=0;
    189         scanf("%I64d %d",&sum,&q);
    190 
    191         for(i=0; i<pnum&&prime[i]*prime[i]<=sum&&sum!=1; i++)
    192         {
    193             if(sum%prime[i]==0)//素数存起来
    194             {
    195                 sol[con].p=prime[i];
    196                 sol[con].init();
    197                 con++;
    198                 while(sum%prime[i]==0)sum/=prime[i];
    199             }
    200         }
    201         if(sum>1)
    202         {
    203             sol[con].p=sum;
    204             sol[con].init();
    205             con++;
    206         }
    207 
    208         printf("Case #%d:
    ",cas++);
    209 
    210         for(i=0; i<q; i++)
    211         {
    212             scanf("%lld %lld",&x,&y);
    213 
    214             ll res=1e18,tmp;
    215             for(j=0; j<con; j++)
    216             {
    217  
    218                 tmp=sol[j].query(x,y);
    219                 if(tmp!=-1)res=min(res,tmp);
    220             }
    221             if(res==1e18)res=-1;
    222             printf("%I64d
    ",res);
    223         }
    224     }
    225     return 0;
    226 }
     
  • 相关阅读:
    setHapticFeedbackEnabled在androi的作用
    Android 跑马灯
    jQuery中绑定事件的命名空间详解
    可见即所得的CSS编辑设计
    盘点8种CSS实现垂直居中水平居中的绝对定位居中技术
    用到的知识点
    用PS去除图片中文字的6个方法
    html页面头部里的meta
    px pt em对应关系
    phpMyAdmin安装与配置(涉及LAMP配置)
  • 原文地址:https://www.cnblogs.com/yuyixingkong/p/4722835.html
Copyright © 2020-2023  润新知