洛谷 P5104:红包发红包 ← 快速幂 + 费马小定理

【题目来源】
https://www.luogu.com.cn/problem/P5104

【题目描述】
红包(redbag)发明了一个抢红包的系统。
这个抢红包系统是这样的:假如现在有 w 元,那么你抢红包能抢到的钱就是 [0,w] 等概率均匀随机出的一个实数 x。
现在红包发了一个 w 元的红包,有 n 个人来抢。那么请问第 k 个人期望抢到多少钱?
输出答案对 10^9+7 取模后的结果。

【输入格式】
一行三个整数,w,n,k。

【输出格式】
第 k 个人期望抢到的钱数对 10^9+7 取模后的结果。

【输入样例】
2 1 1​​​​​​​

【输出样例】
1

【数据范围】
注意红包发明的抢红包系统和微信的抢红包系统不一样,红包发明的抢红包系统中的钱不一定是整数分。
对于 30% 的数据,k=1。
另有 30% 的数据,期望值取模前为整数,k≤10。
对于全部数据,0<w<(10^9+7),n≤10^18,k≤n。

【算法分析】
● 快速幂:https://blog.csdn.net/hnjzsyjyj/article/details/143168167

● 费马小定理:若 p 为质数,且整数 a 满足 gcd(a,p)=1,则 a^(p-1)≡1(mod p)。
费马小定理表明,在模质数 p 下,a 的 p-1 次幂同余于 1。

● 费马小定理与模逆元的联系
(1)逆元定义:若 ax≡1(mod p),则 x 称为 a 的模 p 逆元,记作 a^(-1)。
(2)逆元求解:由费马小定理 a^(p-1)≡1(mod p) 知 a×a^(p-2)≡1(mod p),据此可推导
出 a 的逆元 a^(-1)≡a^(p-2) (mod p)。
(3)模数约束:模数 p 必须为质数。​​​​​​​

● 在区间 0 到 x 之间随机且均匀地取一个数,其长期平均值必然是区间的中点,也就是 x/2。因此,第 k 个人期望领到的红包金额为 w/(2^k),这一等式在模运算下等价于 w 乘以 2^k 的逆元。根据费马小定理,2^k 的逆元等于 2^k 的 MOD−2 次方,该值可以通过快速幂高效求解。

【算法代码】

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int MOD=1e9+7;

int fastPow(LL a,LL b) {
    LL ans=1;
    while(b) {
        if(b & 1) ans=ans*a%MOD;
        a=a*a%MOD;
        b>>=1;
    }
    return ans%MOD;
}

int main() {
    LL w,n,k;
    cin>>w>>n>>k;
    cout<<w*fastPow(fastPow(2,k),MOD-2)%MOD;
}

/*
in:2 1 1
out:1
*/



【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/143135845
https://blog.csdn.net/hnjzsyjyj/article/details/159687664
https://blog.csdn.net/hnjzsyjyj/article/details/146287418


 

posted @ 2026-03-31 21:02  Triwa  阅读(2)  评论(0)    收藏  举报