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(1≤sum≤100000000),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(1≤sum≤100000000,1≤m≤100000) in the first line.
The next m lines will contains two intgeers xi,yi(0≤xi,yi≤1000000000)
For each case, each case contains two integers sum,m(1≤sum≤100000000,1≤m≤100000) in the first line.
The next m lines will contains two intgeers xi,yi(0≤xi,yi≤1000000000)
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.
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
175 =5^2∗7
Hint
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
转载请注明出处:寻找&星空の孩子
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:\n",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\n",res); 223 } 224 } 225 return 0; 226 }
转载请注明出处:http://www.cnblogs.com/yuyixingkong/
自己命运的掌控着!