Mysterious For-HDU 4373

题目描述

MatRush is an ACMer from ZJUT, and he always love to create some special programs. Here we will talk about one of his recent inventions.

This special program was called "Mysterious For", it was written in C++ language, and contain several simple for-loop instructions as many other programs. As an ACMer, you will often write some for-loop instructions like which is listed below when you are taking an ACM contest.

for (int i = 0; i < n; i++) {

for (int j = i; j < n; j++) {

for (int k = j; k < n; k++) {

blahblahblah();

}

}

}

Now, MatRush has designed m for-loop instructions in the "Mysterious For" program, and each for-loop variable was stored in an array a[], whose length is m.

The variable i represents a for-loop instructions is the i-th instruction of the "Mysterious For" program.There only two type of for-loop instructions will occur in MatRush's "Mysterious For" program:

1-type: if a for-loop belongs to 1-type, it will be an instruction like this:

for (int a[i] = 0; a[i] < n; a[i]++) {

...

}

2-type: if a for-loop belongs to 2-type, it will be an instruction like this:

for (int a[i] = a[i - 1]; a[i] < n; a[i]++) {

...

}

In addition, after the deepest for-loop instruction there will be a function called HopeYouCanACIt(), here is what's inside:

void HopeYouCanACIt() {

puts("Bazinga!");

}

So, the "Mysterious For" program, obviously, will only print some line of the saying: "Bazinga!", as it designed for.

For example, we can assume that n equals to 3, and if the program has three 1-type for-loop instructions, then it will run 3 3=27 times of the function HopeYouCanACIt(), so you will get 27 "Bazinga!" in total. But if the program has one 1-type for-loop instruction followed by two 2-type for-loop instructions, then it will run 3+2+1+2+1+1=10 times of that function, so there will be 10 "Bazinga!" on the screen.

Now MatRush has the loop length n and m loop instructions with certain type, then he want to know how many "Bazinga!" will appear on the screen, can you help him? The answer is too big sometimes, so you just only to tell him the answer mod his QQ number:364875103.

All for-loop instructions are surely nested. Besides, MatRush guaranteed that the first one belongs to the 1-type. That is to say, you can make sure that this program is always valid and finite. There are at most 15 1-type for-loop instructions in each program.

Input

First, there is an integer T(T<=50), the number of test cases.

For every case, there are 2 lines.

The first line is two integer n(1<=n<=1000000) and m(1<=m<=100000) as described above.

The second line first comes an integer k(1<=k<=15), represents the number of 1-type loop instructions, then follows k distinctive numbers, each number is the i-th 1-type loop instruction's index(started from 0), you can assume the first one of this k numbers is 0 and all numbers are ascending.

All none 1-type loop instructions of these m one belongs to 2-type.

题目大意

给你循环的类型,和循环的个数,求能循环几次。

分析

扩展Lucas定理+中国剩余定理:大意就是你在mod的p是一个合数,那么就把他拆成p1*p2,两个质数的乘机。

我们可以发现第一类循环最多就只有15个,我的思路的突破口就是在这个15。

我们把这些循环分成一个一个的区块,每一个区块的第一个循环就是第一类循环,那么就是要求出每个循环块的答案在相乘就可以了。

那么我们看到每一个循环块,它的本质就是要取出x个数,但是每一个数都是可以相同的。(注:和每一个数都不一样的不一样,不一样的话答案就非常简单是 \(C^x_n\) )

第一重循环就是n次,第二次循环后面的循环都是第二层循环,那么第二重循环就是\(C^2_{n}+n\),以此类推,那么第三重循环就是$ C^3_{n+2} $,可以理解成在末尾在放两个数,但是所有的数都不能相同。

第三层的推导:

那么我们就得到了结论:第m层循环的次数为\(C^m_{n+m-1}\)

但是由于q不是一个质数,而是两个质数的乘机,所以先用卢卡斯分别求出余数的乘机,再列出等式发现是一个同余方程,就可以使用中国剩余定理或者费马小定理算求解答案。

AC代码

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <queue>
  6. #include <cctype>
  7. #include <cmath>
  8. #include <time.h>
  9. #include <map>
  10. #include <set>
  11. #include <vector>
  12. using namespace std;
  13. #define ms(a,b) memset(a,b,sizeof(a))
  14. typedef long long ll;
  15. const int maxn=1000003;
  16. const int maxm=100003;
  17. const int mod=364875103;
  18. const int mod1=97;
  19. const int mod2=3761599;
  20. int n,m;
  21. ll p1[mod1+10],p2[mod2+10];
  22. void init(){
  23. p1[0]=1,p2[0]=1;
  24. for (int i=1;i<=mod2;i++) p2[i]=p2[i-1]*i%mod2;
  25. for (int i=1;i<=mod1;i++) p1[i]=p1[i-1]*i%mod1;
  26. }
  27. inline int read(){
  28. int X=0,w=0; char ch=0;
  29. while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
  30. while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
  31. return w?-X:X;
  32. }
  33. ll inv(ll x,ll y,ll mod) {
  34. ll ret=1;
  35. while (y) {
  36. if (y&1) ret=ret*x%mod;
  37. x=x*x %mod;
  38. y>>=1;
  39. }
  40. return ret;
  41. }
  42. ll calc1(int n,int m) {
  43. if (n<m) return 0;
  44. ll x1=p1[n],x2=p1[m],x3=p1[n-m];
  45. return x1*inv(x2,mod1-2,mod1)%mod1*inv(x3,mod1-2,mod1)%mod1;
  46. }
  47. ll calc2(int n,int m) {
  48. if (n<m) return 0;
  49. ll x1=p2[n],x2=p2[m],x3=p2[n-m];
  50. return x1*inv(x2,mod2-2,mod2)%mod2*inv(x3,mod2-2,mod2)%mod2;
  51. }
  52. ll lucas2(int n,int m) {
  53. if (n<m) return 0;
  54. if (m==0) return 1;
  55. return calc2(n%mod2,m%mod2)*lucas2(n/mod2,m/mod2)%mod2;
  56. }
  57. ll lucas1(int n,int m) {
  58. if (n<m) return 0;
  59. if (m==0) return 1;
  60. return calc1(n%mod1,m%mod1)*lucas1(n/mod1,m/mod1)%mod1;
  61. }
  62. ll chinese(ll a[]) {
  63. ll x1=inv(mod1,mod2-2,mod2)*a[1]%mod*mod1%mod;
  64. ll x2=inv(mod2,mod1-2,mod1)*a[0]%mod*mod2%mod;
  65. return (x1+x2)%mod;
  66. }
  67. ll solve(int n,int m) {
  68. ll ans[2];
  69. ans[0]=lucas1(n,m);
  70. ans[1]=lucas2(n,m);
  71. return chinese(ans);
  72. }
  73. int main()
  74. {
  75. int cas=read();
  76. init();
  77. for (int t=1;t<=cas;t++) {
  78. n=read(),m=read();
  79. int k=read(),x=read();
  80. ll ans=1;
  81. for (int i=1;i<k;i++) {
  82. int y=read();
  83. ans=ans*solve(n+y-x-1,y-x)%mod;
  84. x=y;
  85. }
  86. ans=ans*solve(n+m-x-1,m-x)%mod;
  87. printf("Case #%d: %lld\n",t,ans);
  88. }
  89. return 0;
  90. }

【Lucas组合数定理+中国剩余定理】Mysterious For-HDU 4373的更多相关文章

  1. Hdu 5446 Unknown Treasure (2015 ACM/ICPC Asia Regional Changchun Online Lucas定理 + 中国剩余定理)

    题目链接: Hdu 5446 Unknown Treasure 题目描述: 就是有n个苹果,要选出来m个,问有多少种选法?还有k个素数,p1,p2,p3,...pk,结果对lcm(p1,p2,p3.. ...

  2. hdu 5446(2015长春网络赛J题 Lucas定理+中国剩余定理)

    题意:M=p1*p2*...pk:求C(n,m)%M,pi小于10^5,n,m,M都是小于10^18. pi为质数 M不一定是质数 所以只能用Lucas定理求k次 C(n,m)%Pi最后会得到一个同余 ...

  3. BZOJ1951 [Sdoi2010]古代猪文 【费马小定理 + Lucas定理 + 中国剩余定理 + 逆元递推 + 扩展欧几里得】

    题目 "在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心--" --选自猪王国民歌 很久很久以前,在山的那 ...

  4. [bzoj2142]礼物(扩展lucas定理+中国剩余定理)

    题意:n件礼物,送给m个人,每人的礼物数确定,求方案数. 解题关键:由于模数不是质数,所以由唯一分解定理, $\bmod  = p_1^{{k_1}}p_2^{{k_2}}......p_s^{{k_ ...

  5. HDU-5446-UnknownTreasure(组合数,中国剩余定理)

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=5446 题意: On the way to the next secret treasure hiding ...

  6. ACM-ICPC 2015 Changchun Preliminary Contest J. Unknown Treasure (卢卡斯定理+中国剩余定理)

    题目链接:https://nanti.jisuanke.com/t/A1842 题目大意:给定整数n,m,k,其中1≤m≤n≤1018,k≤10, 然后给出k个素数,保证M=p[1]*p[2]……*p ...

  7. 逆元 exgcd 费马小定理 中国剩余定理的理解和证明

    一.除法取模逆元 如果我们要通过一个前面取过模的式子递推出其他要取模的式子,而递推式里又存在除法 那么一个很尴尬的事情出现了,假如a[i-1]=100%31=7 a[i]=(a[i-1]/2)%31 ...

  8. 【模拟7.22】visit(卢卡斯定理&&中国剩余定理)

    如此显然的组合数我把它当DP做,我真是.... 因为起点终点已经确定,我们发现如果我们确定了一个方向的步数其他方向也就确定了 组合数做法1: 设向右走了a步,然后向左走了b=a-n步,设向上为c,向下 ...

  9. hdu1573-X问题-(扩展欧几里得定理+中国剩余定理)

    X问题 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

随机推荐

  1. 一文搞懂Ajax,附Ajax面试题

    目录 前言 正文 Ajax是什么东西? 实现核心/工作原理:XMLHttpRequest对象 XMLHttpRequest大致用法 创建XMLHttpRequest对象 发送请求 服务器响应 1. r ...

  2. ieda引入jstl后报错解决办法

    报错如下: HTTP Status 500 - The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in ei ...

  3. 【VBA】读取配置文件存入字典型变量中

    配置文件:  源码: Dim Co As Object '设为全局变量 Function 读取cfg() As Boolean Dim strcfg As String strcfg = " ...

  4. 网页站点下载器teleport ultra

    软件名称:teleport ultra 介绍:teleport ultra是一款专门的网页站点下载器,使用这款工具可以方便地下载网页数据,包括网站的文字.图片.flash动画等,可以轻松下载所有的网站 ...

  5. 测试MySQL锁的问题

    测试MySQL锁的问题 目录 测试MySQL锁的问题 1 Record Lock 2 Next-Key Lock 2 死锁测试 InnoDB支持三种行锁: Record Lock:单个行记录上面的锁 ...

  6. 『心善渊』Selenium3.0基础 — 6、Selenium中使用XPath定位元素

    目录 1.Selenium中使用XPath查找元素 (1)XPath通过id,name,class属性定位 (2)XPath通过标签中的其他属性定位 (3)XPath层级定位 (4)XPath索引定位 ...

  7. webpack(1)安装环境与解决环境问题

    前言 如果我们需要使用webpack,就需要依赖node环境 nvm node npm webpack@cli webpack nvm安装 nvm是一个用来管理node版本的工具.我们之所以需要使用n ...

  8. Unknown custom element: <...> - did you register the component correct?

    之前用过的组件没有出现过任何问题,但偏偏在其他目录下引用就出问题了.组件的名称.import的路径都没任何问题,发现这是因为组件name填写不规范所导致的. 在定义组件的时候我们要严格按照官方文档要求 ...

  9. Java的类加载器种类

    Java类加载器采用双亲委派模型: 1.启动类加载器:这个类加载器负责放在<JAVA_HOME>\lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别 ...

  10. Docker安装MySQL8.0

    环境 CentOS 7.5 Docker 1.13.1 MySQL 8.0.16 安装 拉取镜像 默认拉取最新版本的镜像 $ docker pull mysql 如果要指定版本,使用下面的命令 $ d ...