首页 > 代码库 > [hdu 4869](14年多校I题)Turn the pokers 找规律+拓欧逆元
[hdu 4869](14年多校I题)Turn the pokers 找规律+拓欧逆元
Turn the pokers
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 316 Accepted Submission(s): 101
Problem Description
During summer vacation,Alice stay at home for a long time, with nothing to do. She went out and bought m pokers, tending to play poker. But she hated the traditional gameplay. She wants to change. She puts these pokers face down, she decided to flip poker n times, and each time she can flip Xi pokers. She wanted to know how many the results does she get. Can you help her solve this problem?
Input
The input consists of multiple test cases.
Each test case begins with a line containing two non-negative integers n and m(0<n,m<=100000).
The next line contains n integers Xi(0<=Xi<=m).
Output
Output the required answer modulo 1000000009 for each test case, one per line.
Sample Input
3 4
3 2 3
3 3
3 2 3
Sample Output
8
3
Hint
For the second example:
0 express face down,1 express face up
Initial state 000
The first result:000->111->001->110
The second result:000->111->100->011
The third result:000->111->010->101
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 316 Accepted Submission(s): 101
Problem Description
During summer vacation,Alice stay at home for a long time, with nothing to do. She went out and bought m pokers, tending to play poker. But she hated the traditional gameplay. She wants to change. She puts these pokers face down, she decided to flip poker n times, and each time she can flip Xi pokers. She wanted to know how many the results does she get. Can you help her solve this problem?
Input
The input consists of multiple test cases.
Each test case begins with a line containing two non-negative integers n and m(0<n,m<=100000).
The next line contains n integers Xi(0<=Xi<=m).
Output
Output the required answer modulo 1000000009 for each test case, one per line.
Sample Input
3 4
3 2 3
3 3
3 2 3
Sample Output
8
3
Hint
For the second example:
0 express face down,1 express face up
Initial state 000
The first result:000->111->001->110
The second result:000->111->100->011
The third result:000->111->010->101
So, there are three kinds of results(110,011,101)
题目大意
给定M张牌,可以翻转N次,每次可以翻转恰好Xi张牌,刚开始牌面全部朝下,问经过N次翻转之后可能产生的扑克序列数(如样例hint)。
解题思路
现场还是没出……想到dp的思路但复杂度高达N^2.
可以观察到,我们最后正面朝上的牌的数量奇偶总是一定的(如1,3,5),因为不同奇偶情况就需要至少多翻一次,但翻动的次数已经固定不能更改。
考虑一次翻转,最多X1张牌正面朝上了,最少也是X1张。
如果第二次只翻转1张,再设1<X1<m 则最多会有X1+1张牌正面朝上,最少会有X1-1张牌正面朝上。
现在假设我们已经翻好k-1次
最多a张正面朝上,最少b张正面朝上
如果b>=Xk 则翻转后最少有b-Xk张正面朝上(其余的情况可以一次翻一张正面的,一张反面的,情况保持不变)。
否则,如果a>Xk,这时最少会有0张或1张正面朝上(根据a和Xk的奇偶性判断),
再否则,最少会有Ak-a张正面朝上(先把正面朝上的全部翻转,剩下的再翻便是最少张数)
关于最大值的讨论同理
最后关于组合数的计算,由于m固定不变,就可以根据组合数公式C(m,n)=C(m-1,n)*(n-m+1)/m 线性求解,由于1e9+9是大素数,除法操作可用逆元求解代替。
<span style="font-size:14px;">#include <cstdio> #define LL long long int n,m; LL mod=1000000009; LL a[100005]; void egcd(LL a,LL b,LL &x,LL &y) { if (b==0) { x=1;y=0; return ; } egcd(b,a%b,x,y); LL t=x; x=y,y=t-a/b*y; return; } LL cal(LL x,LL y) { LL cur=1,tmp=0,t=0; while(t<=y) { if (t>=x&&t<=y) if ((t-x)%2==0) tmp=(tmp+cur)%mod; t++; cur=cur*(m-t+1)%mod; LL t1,t2; egcd(t,mod,t1,t2); t1=(t1+mod)%mod; cur=cur*t1%mod; } return tmp; } int main() { while (~scanf("%d%d",&n,&m)){ LL upper,lower,plower,pupper; for (int i=1;i<=n;i++) scanf("%I64d",&a[i]); upper=lower=pupper=plower=0; for (int i=1;i<=n;i++) { if (plower>=a[i]) lower-=a[i]; else if (pupper>=a[i]) lower=0+((pupper+a[i])%2==1); else lower=a[i]-pupper; if (pupper+a[i]<=m) upper+=a[i]; else if (plower+a[i]<=m) upper=m-((plower+a[i])%2==1); else {upper=m-(plower+a[i]-m);} plower=lower;//plower代表上一步的最小值 pupper=upper;//pupper代表上一步的最大值 } printf("%I64d\n",cal(lower,upper)); } return 0; }</span>
[hdu 4869](14年多校I题)Turn the pokers 找规律+拓欧逆元
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。