题目链接:I-B站与各唱各的_2022牛客寒假算法基础集训营1 (nowcoder.com)
题目:最近炸鸡块君在逛B站时发现了有趣的视频( 当四鸽各个唱个的能完成一首『夜に駆ける』吗?!_哔哩哔哩_bilibili ),这种视频被称作"各唱各的"挑战,基于此,炸鸡块君提出了一种有趣的"各唱各的"游戏,其具体规则如下:
有n位UP主在翻唱一首共m句的歌曲;n个UP主先各自独立的在不能与其他UP主交流的情况下录制一份唱歌的音频。对于这首歌中的每一句,每个UP主可以选择唱或不唱;在所有UP主都录制完成后,将这nnn份唱歌的音频合到一起。若在合成后的音频中,某一句歌词所有人都没唱或同时被所有人都唱了,则认为这句唱失败了,否则认为这句唱成功了。现在,炸鸡块君想知道:假设这n位UP主都足够聪明,每位UP主都精通编程且有一台计算速度无限快的超级计算机,但UP主之间不能交流,他们的目标是让成功唱出的句子数尽可能多,求期望唱成功的句子数量对10^9+7取模的结果。
思路:从反面出发,1-失败的概率=成功的概率。对于每一句,失败的情况为全部人都唱这句和全部人都不唱这句,则失败的概率=1/2^n+(1-1/2)^n.(当成功的概率=失败的概率=1/2时,其数学期望最大。。。。我蒙的哈哈哈哈ac了就行)。所以成功的概率为(2^n-2)/2^n,数学期望=m*成功的概率。
在mod1e9+7的条件下,2^n的乘法逆元为(2^n)^(mod-2).(费马小定理)
代码:
include<bits/stdc++.h>
using namespace std;
const long long mod=1e9+7;
long long fastpower(long long base,long long power)
{
long long res=1;
while(power>0)
{
if(power&1) res=base*res%mod;
power >>=1;
base=base*base%mod;
}
return res;
}
int main()
{
int t;
long long n,m;
cin >> t;
while(t--)
{
cin >> n >> m;
long long temp=fastpower(2,n);
cout << m*((temp-2)*fastpower(temp,mod-2)%mod)%mod << endl;
}
}