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

Sample Output

27
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 }

 

posted @ 2018-02-27 08:50  wfj_2048  阅读(407)  评论(0编辑  收藏  举报