bzoj2219 数论之神
Description
在ACM_DIY群中,有一位叫做“傻崽”的同学由于在数论方面造诣很高,被称为数轮之神!对于任何数论问题,他都能瞬间秒杀!一天他在群里面问了一个神题: 对于给定的3个非负整数 A,B,K 求出满足 (1) X^A = B(mod 2*K + 1) (2) X 在范围[0, 2K] 内的X的个数!自然数论之神是可以瞬间秒杀此题的,那么你呢?
Input
第一行有一个正整数T,表示接下来的数据的组数( T <= 1000) 之后对于每组数据,给出了3个整数A,B,K (1 <= A, B <= 10^9, 1 <= K <= 5 * 10^8)
Output
输出一行,表示答案
Sample Input
3
213 46290770 80175784
3 46290770 80175784
3333 46290770 80175784
213 46290770 80175784
3 46290770 80175784
3333 46290770 80175784
Sample Output
27
27
297
27
297
HINT
新加数组一组--2015.02.27
正解:原根,离散对数,欧拉函数,中国剩余定理,$bsgs$,$exgcd$。
题解点击这里,我就懒得写了。。
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 #define r64 (2105317) 6 #define inf (1LL<<62) 7 8 using namespace std; 9 10 int p[30],pr[30],num[30],st[30],a,b,x,rhl,tot,top; 11 ll ans; 12 13 il int gi(){ 14 RG int x=0,q=1; RG char ch=getchar(); 15 while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); 16 if (ch=='-') q=-1,ch=getchar(); 17 while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); 18 return q*x; 19 } 20 21 il int qpow(RG int a,RG int b,RG ll p){ 22 RG int ans=1; 23 while (b){ 24 if (b&1) ans=1LL*ans*a%p; 25 if (b>>=1) a=1LL*a*a%p; 26 } 27 return ans; 28 } 29 30 il int getg(RG int p,RG int phi){ 31 RG int x=phi; top=0; 32 for (RG int i=2;i*i<=x;++i){ 33 if (x%i) continue; 34 while (!(x%i)) x/=i; st[++top]=i; 35 } 36 if (x!=1) st[++top]=x; 37 for (RG int g=2,i;;++g){ 38 for (i=1;i<=top;++i) 39 if (qpow(g,phi/st[i],p)==1) break; 40 if (i>top) return g; 41 } 42 return 0; 43 } 44 45 struct hash{ 46 47 struct edge{ int nt,to,dis; }g[100005]; 48 49 int head[r64+5],st[r64+5],num,top; 50 51 il void init(){ 52 for (RG int i=1;i<=top;++i) head[st[i]]=0; top=num=0; return; 53 } 54 55 il void insert(RG int from,RG int to,RG int dis){ 56 g[++num]=(edge){head[from],to,dis},head[from]=num; return; 57 } 58 59 il void add(RG int x,RG int v){ 60 RG int base=x%r64; 61 if (!head[base]) st[++top]=base; insert(base,x,v); return; 62 } 63 64 il int query(RG int x){ 65 RG int base=x%r64; 66 for (RG int i=head[base];i;i=g[i].nt) 67 if (g[i].to==x) return g[i].dis; 68 return -1; 69 } 70 71 }hsh; 72 73 il int bsgs(RG int a,RG int b,RG int p){ 74 RG int m=ceil(sqrt(p)); hsh.init(); 75 for (RG int i=0,t=b;i<=m;++i,t=1LL*t*a%p) hsh.add(t,i); 76 for (RG int i=1,t=qpow(a,m,p),x=t,y;i<=m;++i,x=1LL*x*t%p) 77 if (~(y=hsh.query(x))) return i*m-y; 78 return -1; 79 } 80 81 il int gcd(RG int a,RG int b){ return b ? gcd(b,a%b) : a; } 82 83 il void work(){ 84 a=gi(),b=gi(),rhl=gi()<<1|1,x=rhl,tot=0; 85 for (RG int i=2;i*i<=x;++i){ 86 if (x%i) continue; p[++tot]=i,pr[tot]=1,num[tot]=0; 87 while (!(x%i)) x/=i,pr[tot]*=i,num[tot]++; 88 } 89 if (x!=1) p[++tot]=x,pr[tot]=x,num[tot]=1; ans=1; 90 for (RG int i=1;i<=tot;++i) 91 if (!(b%pr[i])) ans=ans*qpow(p[i],num[i]-(num[i]-1)/a-1,inf); else{ 92 RG int B=b,cnt=0; 93 while (!(B%p[i])) B/=p[i],pr[i]/=p[i],--num[i],++cnt; 94 if (cnt%a){ ans=0; break; } RG int phi; 95 if (pr[i]!=1) phi=pr[i]/p[i]*(p[i]-1); else phi=1; 96 RG int g=getg(pr[i],phi),t=bsgs(g,B%pr[i],pr[i]); 97 if (t==-1){ ans=0; break; } RG int G=gcd(a,phi); 98 if (t%G){ ans=0; break; } ans*=G*qpow(p[i],cnt-cnt/a,inf); 99 } 100 printf("%lld\n",ans); return; 101 } 102 103 int main(){ 104 #ifndef ONLINE_JUDGE 105 freopen("god.in","r",stdin); 106 freopen("god.out","w",stdout); 107 #endif 108 RG int T=gi(); 109 while (T--) work(); 110 return 0; 111 }