HDU 4869 Turn the pokers 组合数学

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4869

题意:有M张牌背面朝上,进行N次翻牌,每次翻Xi张(可以不连续),问进行N次翻牌后,最后所有牌面朝上朝下有多少种不同的情况。

思路:做比赛的时候有一些模糊的想法,赛后想来当时想的是正确的,不过当时逗比的去做了1005还没出(不是马后炮,捂脸哭)。其实面朝上的牌的数量是在一个固定的范围内的。由于翻开一张牌再翻回去要两次操作,所以朝上的牌的数量是同奇偶性的。两边的界限l和r是根据每次翻开牌的数量决定的。对于l有三种情况,r也有三种情况,很好理解,详见代码。然后就是用逆元求C(N,M)。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
#include <ctype.h>
#include <algorithm>
#include <string>
#include <set>
#define PI acos(-1.0)
#define maxn 10005
#define INF 0x7fffffff
#define eps 1e-8
#define MOD 1000000009
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
long long ex_gcd(long long a, long long b, long long &d, long long &x, long long &y)
{
    if (!b)
    {
        x=1;
        y=0;
        d=a;
    }
    else
    {
        ex_gcd(b,a%b,d,y,x);
        y-=(a/b)*x;
    }
}
int inv(long long a,long long m)
{
    long long d,x,y;
    ex_gcd(a,m,d,x,y);
    if (d==1)
    {
        x=(x%m+m)%m;
        return x;
    }
    else return -1;
}
int main()
{
    int tot,t,m;
    long long c[100005];
    while(~scanf("%d%d",&tot,&m))
    {
        int l=0,r=0,x;
        for(int i=0; i<tot; i++)
        {
            scanf("%d",&x);
            int ll,rr;
            if(x<=l)
                ll=l-x;
            else if(x<r)
                ll=((x&1)==(l&1))?0:1;
            else
                ll=x-r;
            if(x+r<=m)
                rr=x+r;
            else if(x+l<=m)
                rr=(((l+x)&1)==(m&1))?m:m-1;
            else rr=2*m-(l+x);
            l=ll;
            r=rr;
        }
        long long ans=0;
        c[0]=1;
        if(0==l)
            ans+=c[0];
        for(int i=1; i<=r; i++)
        {
            c[i]=(((c[i-1]*(m-i+1))%MOD)*(inv(i,MOD)))%MOD;
            if(i>=l&&((i+l)&1)==0)
                ans=(ans+c[i])%MOD;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}
时间: 2025-01-04 16:42:22

HDU 4869 Turn the pokers 组合数学的相关文章

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(推理)

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

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