Mysterious For

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 694    Accepted Submission(s): 264

Problem Description
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 33=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.
 
Output
For each certain "Mysterious For" program, output one line, "Case #T: ans", where T stands for the case number started with 1, and ans is the number of "Bazinga!" mod 364875103.
 
Sample Input
5
3 3
3 0 1 2
3 3
1 0
3 3
2 0 2
4 4
4 0 1 2 3
10 10
10 0 1 2 3 4 5 6 7 8 9
 
Sample Output
Case #1: 27
Case #2: 10
Case #3: 18
Case #4: 256
Case #5: 148372219

Hint

For the third program, the code is like this:
for (int a[0] = 0; a[0] < n; a[0]++) {
for (int a[1] = a[0]; a[1] < n; a[1]++) {
for (int a[2] = 0; a[2] < n; a[2]++) {
HopeYouCanACIt();
}
}
}
Because n = 3, the answer is 3*3+2*3+1*3=18.

 题意:
m个for循环嵌套,有两种形式,第一类从1开始到n,第二类从上一层循环当前数开始到n,第一层一定是第一种类型,问总的循环的次数对364875103取余的结果。
思路:中国剩余定理+lucas定理;
下面我转载一篇写得不错的思路的一部分
{首先可以看出,每一个第一类循环都是一个新的开始,与前面的状态无关,所以可以把m个嵌套分为几个不同的部分,每一个部分由第一类循环开始,最终结果相乘就可以。
剩下的就是第二类循环的问题,假设一个m层循环,最大到n,
只有第一层:循环n次。C(n, 1)
只有前两层:循环n + (n - 1) + ... + 1 = (n + 1) * n / 2 = C(n + 1, 2);}
接下来是我自己的证明:
有m层循环,然后每层n个;
我们考虑最后一层,然后我们可以用dp的思想,最后一层的第一个数的次数为,C(m-1,m-1),第二个数可以接在上一层,以小于等于第二个结尾的数的后面,那么就是C(m,m-1),同理可以得到剩下的数被计数的个数为C(m+k-1,m-1);
那么这个总的循环次数就是C(m-1,m-1)+C(m,m-1)+C(m+1,m-1)....+C(m+k-1,m-1)+...C(m+n-2,m-1)=
C(m)(m)+C(m,m-1)+C(m+1,m-1)+....C(m+n-2,m-1)根据杨辉三角合并就可得到最终的答案为C(n+m-1,m);
要完整的证明还要用数学归纳法;
然后,我们发现mod不是素数,我们拆分成97*(mod/97);两个素数分别取模,然后用中国剩余定理求出对于mod的模数,同时组合数对97取模用lucas定理,对另一个比较大的直接费马小定理即可。
 

  1 #include <cstdio>
2 #include <cstdlib>
3 #include <cstring>
4 #include <cmath>
5 #include <iostream>
6 #include <algorithm>
7 #include <map>
8 #include <queue>
9 #include <vector>
10 using namespace std;
11 typedef long long LL;
12 bool flag[1000005];
13 LL N1[1200005];
14 LL N2[1200005];
15 const LL mod1=97;
16 const LL mod2=364875103/97;
17 LL quick(LL n,LL m,LL p);
18 LL lucas(LL n,LL m,LL p);
19 pair<LL,LL> CHA(LL *a,LL n,LL *b);
20 LL a[10];
21 LL b[10];
22 int main(void)
23 {
24 LL i,j;
25 int ca=0;
26 int k;
27 scanf("%d",&k);
28 LL n,m;
29 N1[0]=1;
30 N2[0]=1;
31 N2[1]=1;
32 N1[1]=1;
33 for(i=2; i<1200005; i++)
34 {
35 N1[i]=(N1[i-1]*i)%mod1;
36 N2[i]=(N2[i-1]*i)%mod2;
37 }
38 while(k--)
39 {
40 ca++;
41 scanf("%lld %lld",&n,&m);
42 LL s;
43 for(i=0; i<1000005; i++)
44 flag[i]=false;
45 scanf("%lld",&s);
46 LL t;
47 for(i=0; i<s; i++)
48 {
49 scanf("%lld",&t);
50 flag[t]=true;
51 }
52 LL ack=1;
53 LL alk=1;
54 for(i=0; i<m;)
55 {
56 if(flag[i]&&(flag[i+1]&&i!=m-1||i==m-1))
57 {
58 ack=ack*n%mod1;
59 alk=alk*n%mod2;
60
61 i++;
62 }
63 else
64 {
65 for(j=i+1; j<m; j++)
66 {
67 if(flag[j])
68 break;
69 }
70 LL cc=j-i;
71 i=j;
72 LL x=N2[n+cc-1];
73 LL y=N2[cc]*N2[n-1];
74 x=x*quick(y,mod2-2,mod2)%mod2;
75 LL ap=lucas(cc,n+cc-1,mod1);
76 ack=ack%mod1*ap%mod1;
77 alk=alk%mod2*(x)%mod2;
78 }
79 }
80 LL sum=mod1*mod2;
81 memset(a,0,sizeof(a));
82 memset(b,0,sizeof(b));
83 a[0]=mod1;
84 b[0]=ack;
85 b[1]=alk;
86 a[1]=mod2;
87 LL an=0;
88 pair<LL,LL>NA=CHA(a,2,b);
89 printf("Case #%d: %lld\n",ca,NA.first%(mod1*mod2));
90 }
91 return 0;
92 }
93 pair<LL,LL> CHA(LL *a,LL n,LL *b)
94 {
95 int i,j;
96 LL sum=1;
97 LL answer=0;
98 for(i=0; i<n; i++)
99 {
100 sum*=a[i];
101 }
102 for(i=0; i<n; i++)
103 {
104 LL t=sum/a[i];
105 LL ni=quick(t,a[i]-2,a[i]);
106 LL ask=ni*b[i]%sum;
107 ask=ask*t%sum;
108 answer+=ask;
109 answer%=sum;
110 }
111 return make_pair(answer,sum);
112 }
113 LL quick(LL n,LL m,LL p)
114 {
115 n%=p;
116 LL ak=1;
117 while(m)
118 {
119 if(m&1)
120 {
121 ak=ak*n%p;
122 }
123 n=n*n%p;
124 m/=2;
125 }
126 return ak;
127 }
128 LL lucas(LL n,LL m,LL p)
129 {
130 if(n==0)
131 {
132 return 1;
133 }
134 else
135 {
136 LL nx=n%p;
137 LL ny=m%p;
138 if(nx>ny)
139 {
140 return 0;
141 }
142 else
143 {
144 LL x=N1[nx]*N1[ny-nx]%p;
145 LL y=quick(x,p-2,p)*N1[ny]%p;
146 return y*lucas(n/p,m/p,p)%p;
147 }
148 }
149 }

Mysterious For(hdu4373)的更多相关文章

  1. 【转】get a mysterious problem,when i use HttpWebRequest in unity c# script

    in script,i use HttpWebRequest to get service from network.but it comes a mysterious problem. the so ...

  2. D - Mysterious Present

    这个题和求最长递增序列的题类似,为了能输出一组可行的数据,我还用了一点儿链表的知识. Description Peter decided to wish happy birthday to his f ...

  3. codeforces Gym 100187H H. Mysterious Photos 水题

    H. Mysterious Photos Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/p ...

  4. 黑龙江省第七届大学生程序设计竞赛-Mysterious Organization

    描述 GFW had intercepted billions of illegal links successfully. It has much more effect. Today, GFW i ...

  5. D. Mysterious Present (看到的一个神奇的DP,也可以说是dfs)

    D. Mysterious Present time limit per test 2 seconds memory limit per test 64 megabytes input standar ...

  6. (20)The most mysterious star in the universe

    https://www.ted.com/talks/tabetha_boyajian_the_most_mysterious_star_in_the_universe/transcript00:12E ...

  7. qq飞车精灵家园里的背景音乐:Mysterious Town pooka 下载

      一直都觉得Mysterious Town pooka特别好听,但是酷狗音乐和网上直接搜搜不到,于是我直接从源文件中找了出来.虽然是.ogg格式,但是在酷狗音乐里还是可以播放的.貌似是<奥丁领 ...

  8. LightOJ 1220 Mysterious Bacteria(唯一分解定理 + 素数筛选)

    http://lightoj.com/volume_showproblem.php?problem=1220 Mysterious Bacteria Time Limit:500MS     Memo ...

  9. IEEEXtreme 10.0 - Mysterious Maze

    这是 meelo 原创的 IEEEXtreme极限编程大赛题解 Xtreme 10.0 - Mysterious Maze 题目来源 第10届IEEE极限编程大赛 https://www.hacker ...

随机推荐

  1. 详解getchar()函数与缓冲区

    1.首先,我们看一下这段代码: 它的简单意思就是从键盘读入一个字符,然后输出到屏幕.理所当然,我们输入1,输出就是1,输入2,输出就是2. 那么我们如果输出的是12呢? 它的输出是1. 这里我们先简单 ...

  2. 日常Java(测试 (二柱)修改版)2021/9/22

    题目: 一家软件公司程序员二柱的小孩上了小学二年级,老师让家长每天出30道四则运算题目给小学生做. 二柱一下打印出好多份不同的题目,让孩子做了.老师看了作业之后,对二柱赞许有加.别的老师闻讯, 问二柱 ...

  3. Hadoop的HA机制浅析

    Zookeeper在Hadoop的HA中的应用 非HA的弊端: HDFS集群的分布式存储是靠namenode节点(namenode负责响应客户端请求)来实现.在非HA集群中一旦namenode宕机,虽 ...

  4. 数仓day02

    1. 什么是ETL,ETL都是怎么实现的? ETL中文全称为:抽取.转换.加载  extract   transform  load ETL是传数仓开发中的一个重要环节.它指的是,ETL负责将分布的. ...

  5. css系列,选择器权重计算方式

    CSS选择器分基本选择器(元素选择器,类选择器,通配符选择器,ID选择器,关系选择器), 属性选择器,伪类选择器,伪元素选择器,以及一些特殊选择器,如has,not等. 在CSS中,权重决定了哪些CS ...

  6. java Map集合类

    ---恢复内容开始--- Map提供了一个更通用的元素存储方法,Map集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值. 了解Map接口和方法 ...

  7. matplotlib如何绘制直方图、条形图和饼图

    1 绘制直方图: import matplotlib.pyplot as plt import numpy as np import matplotlib def hist1(): # 设置matpl ...

  8. 修改页面.JSP

    <%@ page contentType="text/html;charset=UTF-8" language="java" %><%@tag ...

  9. linux重启后JDk环境变量配置失效最终解决方案

    最终解决方案:https://bbs.deepin.org/forum.php?mod=viewthread&tid=147762 其实这个修改可能也存在问题,如果有耐心的可以每次打开终端   ...

  10. 转:addChildViewController实现网易新闻首页切换

    本来只是打算介绍一下addChildViewController这个方法的,正好今天朋友去换工作面试问到网易新闻标签栏效果的实现,就结合它,用个小Demo实例介绍一下:(具体解释都写在了Demo里面的 ...