问题描述:

林记在做数学习题的时候,经常遇到这种情况:苦思冥想了很久终于把问题解出来,结果发现答案是0,久而久之林记在得到习题答案是0的时候就没有了做出一道难题的成就感。于是林记决定:以后出题,答案一定不能是0,例如求n!最低位非零数这样的习题就很不错了。

现在林记提出了一个更难一点的问题:求n!在K进制下的最低位非零数。其中K符合一些特殊的条件:K是由若干个互不相同的质数相乘得出来的,例如K=2,3,5,6,7,10……

输入格式:

首先输入的第一行是一个整数Q,表示询问的个数。

接下来是Q个询问,每个询问有两行组成,第一行首先是一个整数nk,然后紧跟着nk个正整数:m1,m2,……mnk,则K为所有mi的乘积,输入保证mi是有若干个互不相同的质数相乘得出来的。接下来一行给出一个整数n。

输出格式:

对于每个询问,如果K不符合题目限制,则输出“I hate zero.”(不用加双引号)。否则输出K进制下n!的最低位非零数。

输入样例:

输出样例:

3

1 17

9

1 6

49

1 93

16

15

2

78

数据范围:

对于10%的数据满足:n≤10,K≤100

对于50%的数据满足:n≤100000,K≤100

对于100%的数据满足:n≤1015,K≤1015,mi≤106,Q≤20

【分析】

  快速求阶乘大法!!

  下面某步还用到 威尔逊定理 (p-1)!%p=p-1...... (也可以预处理出来的)

  把m分解质因数,对于质数p单独求n!=p^a+b的a的值和b%p的值(logn递归搞定),然后用中国剩余定理合并起来。

  

  long long的乘积会爆,所以...要用那个不断乘2的方法:

  

  1. LL mul(LL x,LL y,LL p)
  2. {
  3. if(x==0||y==0) return 0;
  4. LL now=x,yy=y,add=0;
  5. while(yy>1)
  6. {
  7. if(yy%2!=0) add=(add+now)%p;
  8. now=(now*2)%p;
  9. yy/=2;
  10. }
  11. return (now+add)%p;
  12. }

代码如下:

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<queue>
  7. #include<cmath>
  8. using namespace std;
  9. #define Maxn 1000010
  10. #define INF 0xfffffff
  11. #define LL long long
  12.  
  13. LL nk,m[Maxn],ml,K;
  14. LL n;
  15. LL prime[Maxn],pl;
  16. bool q[Maxn];
  17. LL mn;
  18.  
  19. LL mymin(LL x,LL y) {return x<y?x:y;}
  20.  
  21. void get_pri(LL mx)
  22. {
  23. pl=;
  24. memset(q,,sizeof(q));
  25. for(LL i=;i<=mx;i++)
  26. {
  27. if(q[i]) prime[++pl]=i;
  28. for(int j=;j<=pl;j++)
  29. {
  30. if(i*prime[j]>mx) break;
  31. q[i*prime[j]]=;
  32. if(i%prime[j]==) break;
  33. }
  34. }
  35. }
  36.  
  37. bool div(LL mm)
  38. {
  39. for(LL i=;prime[i]*prime[i]<=mm;i++) if(mm%prime[i]==)
  40. {
  41. m[++ml]=prime[i];
  42. mm/=prime[i];
  43. while(mm%prime[i]==) return ;
  44. }
  45. if(mm!=) m[++ml]=mm;
  46. return ;
  47. }
  48.  
  49. bool init()
  50. {
  51. ml=;
  52. scanf("%lld",&nk);
  53. K=;
  54. bool ok=;
  55. for(int i=;i<=nk;i++)
  56. {
  57. LL mm;
  58. scanf("%lld",&mm);K*=mm;
  59. if(!div(mm)) ok=;
  60. }
  61. sort(m+,m++ml);
  62. for(LL i=;i<=ml;i++) if(m[i]==m[i-]) {ok=;break;}
  63. scanf("%lld",&n);
  64. if(!ok) return ;
  65. return ;
  66. }
  67.  
  68. LL f[Maxn];
  69.  
  70. struct node{LL x,y;};
  71. node c[Maxn];
  72.  
  73. node ffind(LL x,LL p)
  74. {
  75. node ans;
  76. if(x<p)
  77. {
  78. ans.x=;
  79. ans.y=f[x];
  80. return ans;
  81. }
  82. ans.x=;ans.y=;
  83. node t=ffind(x/p,p);
  84. ans.x+=t.x; ans.y*=t.y;
  85. ans.y=(ans.y*f[x%p])%p;
  86. ans.x+=x/p;
  87.  
  88. LL y=(((x/p)%)==)?:p-;
  89. ans.y=(ans.y*y)%p;
  90.  
  91. return ans;
  92. }
  93.  
  94. LL mul(LL x,LL y,LL p)
  95. {
  96. if(x==||y==) return ;
  97. LL now=x,yy=y,add=;
  98. while(yy>)
  99. {
  100. if(yy%!=) add=(add+now)%p;
  101. now=(now*)%p;
  102. yy/=;
  103. }
  104. return (now+add)%p;
  105. }
  106.  
  107. LL qpow(LL x,LL b,LL p)
  108. {
  109. LL ans=;
  110. while(b)
  111. {
  112. if(b&) ans=mul(ans,x,p);
  113. x=mul(x,x,p);
  114. b>>=;
  115. }
  116. return ans;
  117. }
  118.  
  119. LL d[Maxn];
  120.  
  121. LL get_ans()
  122. {
  123. mn=c[].x;
  124. for(LL i=;i<=ml;i++) mn=mymin(mn,c[i].x);
  125. for(LL i=;i<=ml;i++)
  126. {
  127. if(c[i].x>mn) {d[i]=;continue;}
  128. LL bm=qpow(K/m[i],mn,m[i]);
  129. bm=qpow(bm,m[i]-,m[i]);
  130. d[i]=mul(bm,c[i].y,m[i]);//(bm*c[i].y)%m[i];
  131. }
  132. LL ans=;
  133. for(LL i=;i<=ml;i++)
  134. {
  135. LL y=qpow(K/m[i],m[i]-,m[i]);
  136. //ans=(ans+((K/m[i]*y)%K)*d[i])%K;
  137. ans=(ans+mul(mul(K/m[i],y,K),d[i],K))%K;
  138. }
  139. return ans;
  140. }
  141.  
  142. int main()
  143. {
  144. get_pri();
  145. int T;
  146. scanf("%d",&T);
  147. while(T--)
  148. {
  149. if(!init()) {printf("I hate zero.\n");continue;}
  150. for(LL i=;i<=ml;i++)
  151. {
  152. f[]=;
  153. for(LL j=;j<m[i];j++) f[j]=(f[j-]*j)%m[i];
  154. c[i]=ffind(n,(LL)m[i]);
  155. }
  156. printf("%lld\n",get_ans());
  157. }
  158. return ;
  159. }

2016-09-04 19:37:26

【GDOI 2011 DAY2 T3】零什么的最讨厌了 (快速求阶乘、中国剩余定理)的更多相关文章

  1. 【NOIP 2017】Day2 T3 列队

    Problem Description \(Sylvia\) 是一个热爱学习的女孩子. 前段时间,\(Sylvia\) 参加了学校的军训.众所周知,军训的时候需要站方阵. \(Sylvia\) 所在的 ...

  2. 数论-质数 poj2689,阶乘分解,求阶乘的尾零hdu1124, 求尾零为x的最小阶乘

    /* 要求出[1,R]之间的质数会超时,但是要判断[L,R]之间的数是否是素数却不用筛到R 因为要一个合数n的最大质因子不会超过sqrt(n) 所以只要将[2,sqrt(R)]之间的素数筛出来,再用这 ...

  3. 【BZOJ 4518】【SDOI 2016 Round1 Day2 T3】征途

    比较明显的斜率优化DP,省选时因为时间太紧张和斜率DP写得不熟等原因只写了60分的暴力DP,其实当时完全可以对拍来检验标算的正确,但是我当时too naive- 很快打完了,调了将近一晚上QAQ,因为 ...

  4. 【NOIP 2013 DAY2 T3】 华容道(spfa)

    题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时间. 小 ...

  5. 【NOIP 2015 DAY2 T3】 运输计划 (树链剖分-LCA)

    题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...

  6. 【NOIP2015提高组】 Day2 T3 运输计划

    题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家物流公司,该公司有很多个运输计划,每个运输计划形如: ...

  7. 一道搜索题【2013 noip提高组 DAY2 t3】华容道

    这篇不多说,具体的解释都在程序里 题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果 ...

  8. 【NOIP 2015】Day2 T3 运输计划

    Problem Background 公元 \(2044\) 年,人类进入了宇宙纪元. Description 公元\(2044\) 年,人类进入了宇宙纪元. $L $国有 \(n\) 个星球,还有 ...

  9. 【NOIP 2016】Day2 T3 愤怒的小鸟

    Problem Description \(Kiana\) 最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 \((0,0)\) 处,每次 \(Kiana\ ...

随机推荐

  1. 微信公众号支付(一):获取用户openId

    一.获取apikey,appsecret与商户号 注册公众号.商户号 二.获取用户的OpenId 1.设置[授权回调页面域名] 官方解释:用户在网页授权页同意授权给公众号后,微信会将授权数据传给一个回 ...

  2. 在Vivado中调用ModelSim生成FSM的状态转移图

    如果我们已经书写了一段FSM代码,现在想倒过来把它转换成为状态转移图,方便我们直观地检查我们书写的状态对不对(在写论文什么的画图太麻烦的时候,有个自动生成的是多方便啊!),应该怎么弄呢?通过在Viva ...

  3. Hibernate缓存杂谈

    1.什么是缓存? 缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存中的容器,其作用是为了减少应用程序对物理数据源访问的次数,从而提高了应用程序的运行性能.Hibernate在 ...

  4. 20160324 javaweb 之request

    package com.dzq.servlet; import java.io.IOException; import javax.servlet.ServletException; import j ...

  5. WildFly 9.0.2+mod_cluster-1.3.1 集群配置

    一.配置背景 最近使用WildFly 9.0.2作为中间件开发系统,给客户不熟的时候需要使用集群来进行负载均衡,一开始想到是使用Nginx.但是只通过Nginx使用 ip_hash 模式没有做到ses ...

  6. 常见错误总结_1_对java类进行修改后,无法按修改的类型加载

    1.这是因为没有run的原因,对类进行修改一定要run一遍 2.至于要不要重新tomcat部署,取决于你是修改了变量还是方法,拿不定的时候都重新加载一遍看看.

  7. c# linq 基础知识点

    1.Where与TakeWhile,Where和sql中的where一样,返回所有满足条件的元素,而TakeWhile判断原理类似于while语句,从头逐个判断,只要条件为真就一直返回检索到的元素,只 ...

  8. C/C++随机数rand()和种子函数srand()

    在计算机编程中,常常要产生一个随机数.但是要让计算机产生一个随机数并不那么容易.计算机的执行,是以代码来进行的,所以并不可能像抽牌,扔骰子那样产生一个真正具有随机意义的数.只可能以一定的算法产生一个伪 ...

  9. File的文件提取的小练习

    package com.java.Dmeo1.www; import java.io.File;import java.util.LinkedList;import java.util.TreeSet ...

  10. C#控件命名规范

    文档名称: C#控件命名规范 撰写作者: codefly 版本编号: V1.1 C#控件命名规范 一.Data Control 类型 前缀 示例 AccessDataSource ads adsPub ...