记录编号 230845 评测结果 AAAAAAAAAA
题目名称 多-有丝分裂 最终得分 100
用户昵称 GravatarSatoshi 是否通过 通过
代码语言 C++ 运行时间 0.406 s
提交时间 2016-02-24 12:36:46 内存使用 8.59 MiB
显示代码纯文本
  1. #include <fstream>
  2. #include <algorithm>
  3. #include <cmath>
  4. #include <map>
  5. #define N 70000
  6. using namespace std;
  7. typedef long long ll;
  8. ifstream cin("mitotic_division.in");
  9. ofstream cout("mitotic_division.out");
  10. ll add=0;
  11. ll INF=1;
  12. ll splay;
  13. int T;
  14. int cnt=0;
  15. map<ll,int > F;
  16. class Hash_table
  17. {
  18. public:
  19. ll num[10];
  20. int o[10];
  21. int top;
  22. }a[N+10];
  23. ll find(ll x)
  24. {
  25. ll fir,sec;
  26. int i;
  27. fir=x%67481;
  28. sec=x%99991;
  29. for(i=1;i<=a[fir].top;i++)
  30. {
  31. if(sec==a[fir].o[i])return a[fir].num[i];
  32. }
  33. return 0;
  34. }
  35. void insert(ll x,ll y)
  36. {
  37. ll fir,sec;
  38. int i;
  39. fir=x%67481;
  40. sec=x%99991;
  41. for(i=1;i<=a[fir].top;i++)
  42. {
  43. if(sec==a[fir].o[i])
  44. {
  45. a[fir].num[i]=y;
  46. return ;
  47. }
  48. }
  49. a[fir].top++;
  50. a[fir].num[a[fir].top]=y;
  51. a[fir].o[a[fir].top]=sec;
  52. //for(i=1;i<=top;i++)
  53. }
  54. void clear(ll x)
  55. {
  56. ll fir;
  57. fir=x%67481;
  58. a[fir].top=0;
  59. }
  60. ll gcd(ll x,ll y)
  61. {
  62. while(true)
  63. {
  64. if(!x)return y;
  65. if(!y)return x;
  66. if(x>y)x%=y;
  67. else y%=x;
  68. }
  69. }
  70. ll pow(ll a,ll x,ll p)//a^x mod p
  71. {
  72. ll c=1;
  73. while(x)
  74. {
  75. if(x&1)c=(c*a)%p;
  76. a=(a*a)%p;
  77. x=x>>1;
  78. }
  79. return c;
  80. }
  81. void exgcd(ll a,ll b,ll &x,ll &y)//a mod b=1 求逆元
  82. {
  83. if(!b)
  84. {
  85. x=1;
  86. y=0;
  87. }
  88. else
  89. {
  90. exgcd(b,a%b,x,y);
  91. ll t;
  92. t=x;
  93. x=y;
  94. y=t-(a/b)*x;
  95. }
  96. }
  97. void cleard(ll a,ll b,ll c)
  98. {
  99. ll i,temp,mor;
  100. temp=b;
  101. for(i=1;i<splay;i++)
  102. {
  103. temp*=a;
  104. temp%=c;
  105. clear(temp);
  106. }
  107. }
  108. ll work(ll a,ll b,ll c)//真大步小步算法
  109. {
  110. ll i,temp,mor;
  111. temp=b;
  112. //F.clear();
  113. for(i=1;i<splay;i++)
  114. {
  115. temp*=a;
  116. temp%=c;
  117. insert(temp,i);
  118. //F[temp]=i;
  119. }
  120. temp=pow(a,splay,c);
  121. mor=1;
  122. for(i=1;i<=splay+2;i++)
  123. {
  124. mor*=temp;
  125. mor%=c;
  126. if(find(mor))return i*splay-find(mor);
  127. //if(F[mor])return i*splay-F[mor];
  128. if(mor==b)return i*splay;
  129. }
  130. return INF;
  131. }
  132. ll baby_grant(ll a,ll b,ll c)//a^x mod c=b
  133. {
  134. ll d,x,y,ans;
  135. add=0;
  136. //方程转化,使得c为质数或b=1
  137. d=gcd(a,c);
  138. while(d!=1)
  139. {
  140. if(c!=1)
  141. {
  142. a%=c;
  143. b%=c;
  144. }
  145. if(b%d!=0)return INF;//b不整除d,无解
  146. b/=d;c/=d;
  147. exgcd(a/d,c,x,y);
  148. if(x<=0)x+=c;//求逆元
  149. b*=x;
  150. if(c!=1)
  151. {
  152. a%=c;
  153. b%=c;
  154. }
  155. add++;
  156. d=gcd(a,c);
  157. }
  158. splay=ll(sqrt(double(c)));
  159. ans=work(a,b,c);
  160. cleard(a,b,c);
  161. return ans;
  162. }
  163. int main()
  164. {
  165. ll a,b,c,ans;
  166. int T;
  167. INF=INF<<60;
  168. cin>>T;
  169. while(T--)
  170. {
  171. cin>>a>>b>>c;
  172. ans=baby_grant(a,b,c);
  173. if(ans<=INF/100)cout<<ans+add<<endl;
  174. else cout<<"no solution"<<endl;
  175. }
  176. return 0;
  177. }