在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 Input3 213 46290770 80175784 3 46290770 80175784 3333 46290770 80175784Sample Output
新加数组一组--2015.02.27
27 27 297Hint
题解一堆,看看别人的吧 = =
通过这题也学到了不少的东西o_O
1 #include <iostream>
2 #include <algorithm>
3 #include <cstring>
4 #include <cstdio>
5 #include <cmath>
6 #include <cstdlib>
7 #define inf 1e17
8 #define LL long long
9 #include <map>
10 using namespace std;
11 map<LL,LL> mp;
12 struct data
13 {
14 LL p,c,pc;
15 } a[100005];
16 int num,cnt;
17 LL f[100005];
18
19 void Chai(int x)
20 {
21 num=0;
22 for (int i=2; i<sqrt(x+0.5); i++) if (x%i==0)
23 {
24 a[++num].p=i;
25 a[num].c=0,a[num].pc=1;
26 while (x%i==0) x/=i,a[num].c++,a[num].pc*=i;
27 if (x==1) break;
28 }
29 if (x!=1) a[++num].p=x,a[num].pc=x,a[num].c=1;
30 }
31
32 LL Pow(LL x,LL n,LL mod)
33 {
34 LL ans=1,b=x;
35 while (n)
36 {
37 if (n&1) ans=ans*b%mod;
38 b=b*b%mod;
39 n>>=1LL;
40 }
41 return ans;
42 }
43
44 LL GetPrimitiveRoot(LL p,LL phi)
45 {
46 int c=0;
47 for (int i=2; i*i<=phi; i++) if (phi%i==0) f[++c]=i,f[++c]=phi/i;
48 for (int g=2;; g++)
49 {
50 int j;
51 for (j=1; j<=c; j++) if (Pow(g,f[j],p)==1) break;
52 if (j==c+1) return g;
53 }
54 return 0;
55 }
56
57 void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
58 {
59 if (!b)
60 {
61 d=a,x=1,y=0;
62 return;
63 }
64 exgcd(b,a%b,d,y,x);
65 y-=x*(a/b);
66 }
67
68 LL BSGS(LL A,LL B,LL C)
69 {
70 int m=ceil(sqrt(C+0.5));
71 mp.clear();
72 LL now=1;
73 for (int i=1; i<=m; i++)
74 {
75 now=now*A%C;
76 if (!mp[now]) mp[now]=i;
77 }
78 mp[1]=0;
79 A=Pow(A,m,C);
80 now=1LL;
81 for (int i=0; i<=m; i++)
82 {
83 LL d,x,y;
84 exgcd(now,C,d,x,y);
85 x=(x*B%C+C)%C;
86 if (mp.count(x)) return i*m+mp[x];
87 now=now*A%C;
88 }
89 return 0;
90 }
91 LL Gcd(LL a,LL b)
92 {
93 if (!b) return a;
94 return Gcd(b,a%b);
95 }
96 LL Solve(LL A,LL B,LL k)
97 {
98 LL phi=a[k].pc-a[k].pc/a[k].p,g=GetPrimitiveRoot(a[k].pc,phi);
99 LL ind=BSGS(g,B,a[k].pc);
100 LL ans=Gcd(phi,A);
101 if (ind%ans) return 0;
102 return ans*Pow(a[k].p,cnt-cnt/A,inf);
103 }
104 int main()
105 {
106 int T;
107 scanf("%d",&T);
108 while (T--)
109 {
110 LL A,B,k;
111 scanf("%lld%lld%lld",&A,&B,&k);
112 LL p=2*k+1;
113 Chai(p);
114 LL ans=1;
115 for (int i=1; i<=num; i++)
116 {
117 if (!ans) break;
118 if (B%a[i].pc==0) ans=ans*Pow(a[i].p,a[i].c-(a[i].c-1)/A-1,inf);
119 else
120 {
121 int b=B;
122 cnt=0;
123 while ((b%a[i].p)==0) b/=a[i].p, a[i].pc/=a[i].p, a[i].c--,cnt++;
124 if (cnt%A) ans=0;
125 else ans=ans*Solve(A,b,i);
126 }
127 }
128 printf("%lld
",ans);
129 }
130 return 0;
131 }