HDU 4869 Turn the pokers

Turn the pokers

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

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 43 2 33 33 2 3

Sample Output

83

Hint

For the second example:0 express face down,1 express face upInitial state 000The first result:000->111->001->110The second result:000->111->100->011The third result:000->111->010->101So, there are three kinds of results(110,011,101)

区间维护很绕人!!!!!前面把它想简单了,无限跪!!

还有组合数快速幂求模,以前都没记这东西!!!

按题解在赛后总算把它A了!

AC代码如下:

#include<cstdio>
#include<iostream>
#include<cstring>
#define mod 1000000009
#define ll long long
#define M 100005
using namespace std;

ll n,m;
ll a[M],c[M];

ll pow_mod(ll a,ll b)
{
    ll s=1;
    while(b)
    {
        if(b&1)s=s*a%mod;
        a=a*a%mod;
        b=b>>1;
    }
    return s;
}

int main()
{
    ll i,j;
    ll ans,minn,maxx;
    while(~scanf("%lld%lld",&n,&m))
    {

        ans=0;
        ll l=0,r=0;
        for(i=0;i<n;i++)
        {
            scanf("%lld",&a[i]);
            if(a[i]==m||a[i]==0)
                continue;
            if(r+a[i]<=m)//右区间的改变
                maxx=r+a[i];
            else if(l+a[i]<=m)
                maxx=((m+l+a[i])&1)?m-1:m;
            else maxx=m+m-l-a[i];
            if(l-a[i]>=0)//左区间的改变
                minn=l-a[i];
            else if(r-a[i]>=0)
                minn=((l+a[i])&1)?1:0;
            else minn=a[i]-r;
            l=minn;r=maxx;
        }
        //cout<<l<<"~~~~~~~~"<<r<<endl;
        c[0]=1;
        for(ll k=1;k<=m;k++)//组合数快速幂求模
        {
            if(m-k<k)c[k]=c[m-k];
            else c[k]=c[k-1]*(m-k+1)%mod*pow_mod(k,mod-2)%mod;
        }
        for(i=l;i<=r;i+=2)//区间肯定是同奇偶的
            ans=(ans+c[i])%mod;
        printf("%I64d\n",ans);

    }
    return 0;
}
时间: 2024-10-22 00:34:25

HDU 4869 Turn the pokers的相关文章

HDU 4869 Turn the pokers(推理)

HDU 4869 Turn the pokers 题目链接 题意:给定n个翻转扑克方式,每次方式相应能够选择当中xi张进行翻转.一共同拥有m张牌.问最后翻转之后的情况数 思路:对于每一些翻转,假设能确定终于正面向上张数的情况,那么全部的情况就是全部情况的C(m, 张数)之和.那么这个张数进行推理会发现,事实上会有一个上下界,每隔2个位置的数字就是能够的方案,由于在翻牌的时候,相应的肯定会有牌被翻转,而假设向上牌少翻一张,向下牌就要多翻一张.奇偶性是不变的,因此仅仅要每次输入张数,维护上下界,最后

hdu 4869 Turn the pokers(递推&amp;组合数学&amp;逆元)

Turn the pokers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1279    Accepted Submission(s): 466 Problem Description During summer vacation,Alice stay at home for a long time, with nothing t

HDU 4869 Turn the pokers(思维+组合公式+快速幂)

Turn the pokers 大意:给出n次操作,给出m个扑克,然后给出n个操作的个数a[i],每个a[i]代表可以翻的扑克的个数,求最后可能出现的扑克的组合情况. Hint Sample Input: 3 3 3 2 3 For the this example: 0 express face down,1 express face up Initial state 000 The first result:000->111->001->110 The second result:0

hdu 4869 Turn the pokers(数学)

题目链接:hdu 4869 Turn the pokers 题目大意:给定n和m,表示有n次翻牌的机会,m张牌,一开始所有的牌均背面朝上,每次翻牌可以选择xi张牌同时翻转.问说最后有多少种能. 解题思路:只要确定最后正面朝上的牌的个数即可.所以在读入xi的时候维护上下限即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long l

2014多校第一场 I 题 || HDU 4869 Turn the pokers(费马小定理+快速幂模)

题目链接 题意 : m张牌,可以翻n次,每次翻xi张牌,问最后能得到多少种形态. 思路 :0定义为反面,1定义为正面,(一开始都是反), 对于每次翻牌操作,我们定义两个边界lb,rb,代表每次中1最少时最少的个数,rb代表1最多时的个数.一张牌翻两次和两张牌翻一次 得到的奇偶性相同,所以结果中lb和最多的rb的奇偶性相同.如果找到了lb和rb,那么,介于这两个数之间且与这两个数奇偶性相同的数均可取到,然后在这个区间内求组合数相加(若lb=3,rb=7,则3,5,7这些情况都能取到,也就是说最后的

hdu 4869 Turn the pokers (思维)

Turn the pokers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 196    Accepted Submission(s): 51 Problem Description During summer vacation,Alice stay at home for a long time, with nothing to

HDU 4869 Turn the pokers 逆元

题解地址:点击打开链接 题解:最终的结果一定是连续出现的,只需要求出最终的区间.因为如果对同一张牌进行两次操作,牌的状态不改变.故牌的翻转次数一定是减少偶数次.如果所有数的和是奇数,那么最终结果也一定是奇数.同理,偶数也是一样的.所以只要递推求出最后的区间,计算sum(C(xi,m)(i=0,1,2...)),m是总牌数,xi是在区间内连续的奇数或偶数,在模10^9+9就是最终的答案. #include <stdio.h> #include <string.h> #include

HDU 4869 Turn the pokers 多校训练第一场1009

Turn the pokers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 282    Accepted Submission(s): 89 Problem Description During summer vacation,Alice stay at home for a long time, with nothing to

hdu 4869 Turn the pokers (2014多校联合第一场 I)

Turn the pokers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1265    Accepted Submission(s): 465 Problem Description During summer vacation,Alice stay at home for a long time, with nothing t

HDU 4869 Turn The Pokers 思维+组合

HDU 4869题意:m张牌,朝上状态为1,朝下状态为0,现在有n个操作 第i次操作可以反转任意xi张牌初始牌全部朝下,n,m<=1e5,问n次操作后能得到多少种不同的状态? 关心的是最后的状态 假如1有x个 则贡献C(m,x)种状态因为每翻转一次,1的个数和0的个数都相差2. 当每轮最少得到x个1,最多得到y个1 则1的个数范围[x,x+2...y-2,y]中都能取到,维护1的可取个数 组合数累加即可. #include <bits/stdc++.h> using namespace