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 ll;
//typedef __int64 ll;
const ll mod = 1e9+9;
const int maxn = 1e5+10;
int n, m, l, r;
ll c[maxn];

ll pow_mod (ll x, int k) {
    ll ans = 1;
    while (k) {
        if (k&1)
            ans = ans * x % mod;

        x = x * x % mod;
        k /= 2;
    }
    return ans;
}

void init () {
    int x, p, q;
    l = r = 0;
    for (int i = 0; i < n; i++) {
        scanf("%d", &x);

        if (l >= x)
            p = l - x;
        else if (r >= x)
            p = ( (l&1) == (x&1) ? 0 : 1);
        else
            p = x - r;

        if (r + x <= m)
            q = r + x;
        else if (l + x <= m)
            q = ( ((l+x)&1) == (m&1) ? m : m-1);
        else
            q = 2 * m - l - x;
        l = p;
        r = q;
    }
}

ll solve () {
    c[0] = 1;
    ll ans = 0;

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

        if (i) {
            if (m - i < i)
                c[i] = c[m-i];
            else
                //c[i] = c[i-1] * (m-i+1) % mod * pow_mod(i, mod-2)  % mod;
                c[i] = c[i-1] * ( (ll)(m-i+1) * pow_mod(i, mod-2)  % mod) % mod;
        }

        if (i >= l && (i&1) == (l&1))
            ans = (ans + c[i]) % mod;
    }
    return ans;
}

int main () {
    while (scanf("%d%d", &n, &m) == 2) {
        init();
        printf("%lld\n", solve());
    }
    return 0;
}

hdu 4869 Turn the pokers(数学),布布扣,bubuko.com

时间: 2024-11-03 22:10:27

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

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