Codeforces Round #489 (Div. 2) ---- C - Nastya and a Wardrobe

这是一个求期望的题,因为每天有50%的可能出现被吃掉一件衣服的情况,因此这些每天的情况就构成了一颗二叉树

根结点是x ,左节点是 x << 1 -1 右节点是 x << 1 ,那么假设有k天,根据二叉树的性质,在第k天就有2^k个节点,分别为

2^k * x , 2^k*x -1 ,2^k*x - 2, 2^k*x - 3 ……2^k*x - (2^k-1) ,每个情况出现的概率是1 / 2^k 那么最后的答案就是

(2^k * x + 2^k*x -1  + 2^k*x - 2 +  2^k*x - 3 …… 2^k*x - (2^k-1)) / 2^k 化简得  2^k ( 2x - 1 ) + 1

注意到

1、x和k非常大,因此2^k 需要快速幂,2*x-1 要先对mod取模再运算

2 、x可以为0 ,特别坑,加特判过

代码如下

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL gcd(LL a,LL b){if (b == 0) return a; return gcd(b , a%b);}
LL lcm(LL a,LL b){ return a/gcd(a,b)*b;}
inline int read(){
    int f = 1, x = 0;char ch = getchar();
    while (ch > '9' || ch < '0'){if (ch == '-')f = -f;ch = getchar();}
    while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}
const int mod = 1e9 + 7;
LL qpow(LL a,LL b){
    LL base = a % mod,ans = 1;
    while (b) {
        if (b & 1) ans = ans * base % mod;
        base = base * base % mod;
        b >>= 1;
    }
    return ans % mod;
}
int main(){
    LL x, k;
    cin >> x >> k;
    LL ans1 = qpow(2, k);
    LL ans2 = (2*x-1) % mod;
    if (x == 0) { cout << 0 << endl; return 0;}
    else cout << (ans1 * ans2 + 1) % mod << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/CCCCTong/article/details/82715458