链接:https://ac.nowcoder.com/acm/contest/894/C
来源:牛客网题目描述
有一个箱子,开始时有n个黑球,m个蓝球。每一轮游戏规则如下:
第一步:奕奕有p的概率往箱子里添加一个黑球,有(1-p)的概率往箱子里添加一个蓝球。
第二步:华华随机从箱子里取出一个球。
华华喜欢黑球,他想知道k轮游戏之后箱子里黑球个数的期望。输入描述:
输入五个整数n,m,k,a,b。 1<=n,m<=1e6,1<=k<=1e9 其中p=abab,且a<=b,0<=a<1e9+7,0<b<1e9+7输出描述:
输出一个数表示k轮游戏后箱子里黑球个数的期望。 输出一个整数,为答案对1e9+7取模的结果。即设答案化为最简分式后的形式为abab,其中a和b互质。输出整数 x 使得bx≡a(mod 1e9+7)且0≤x<1e9+7。可以证明这样的整数x是唯一的。示例1
输入
2 2 1 1 2输出
2示例2
输入
2 2 2 3 10输出
184000003
题意:如上
思路:求期望题目,一遍是逆推,但是这个好像推不出?看了题解后,我推出来的式子和题解一样,但是过程貌似有点出入,后面再研究研究了。我的思路是,对于第i天的黑球期望 dp[i] = dp[i-1] + p*1 - (dp[i-1] + p*1)(m+n+1),直观上理解,第i天黑球期望等于前一天的期望数加上第一步取得黑球的期望 p*1 ,再减去第二步取出黑球的期望,注意到无论哪一轮,第二步的时候总球数一定是n+m+1,则随机取到黑球期望为 (dp[i-1] + p*1)/(n+m+1)*1。就可以推到dp[i]了。化简后可以用矩阵快速幂算,进一步化简后只需算一个等比数列,用快速幂推就可以了。
题解思路:
注意:本题学的东西还是挺多的,主要是逆元和模方面的细节,以前虽然知道但是没有做过,感觉还是不一样。含模运算过程如果有减法一定要(a-b)%mod = ((a%mod-b%mod)+mod)%mod,不然会出错。
#include<bits/stdc++.h>
#include<iostream>
#include<queue>
#include<cstring>
#include<math.h>
#include<algorithm>
#include<cstdio>
#include<map>
#include<stack>
#include<vector>
#define rep(i,e) for(int i=0;i<(e);++i)
#define rep1(i,e) for(int i=1;i<=(e);++i)
#define repx(i,x,e) for(int i=(x);i<=(e);++i)
#define pii pair<int,int>
#define X first
#define Y second
#define PB push_back
#define MP make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define IOS ios::sync_with_stdio(false);cin.tie(0)
typedef long long ll;
using namespace std;
#ifdef LOCAL
template<typename T>
void dbg(T t){
cout<<t<<" "<<endl;
}
template<typename T, typename... Args>
void dbg(T t, Args... args){
cout<<t<<" ";dbg(args...);
}
#else
#define dbg(...)
#endif // local
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int mod = 1e9+7;
const int N = 1e4+10;
typedef long long ll;
#define K 137
const int maxn = 1e3+10;
const int maxm =4e5+10;
ll qpow(ll x,ll n){
ll res = 1;
while(n){
if(n % 2 == 1)
res = res*x%mod;
x = x*x%mod;
n /= 2;
}
return res;
}
void work(){
ll n,m,k,a,b;
cin>>n>>m>>k>>a>>b;
ll p = a*qpow(b,mod-2)%mod;
ll s = (n+m)%mod*qpow(n+m+1,mod-2)%mod;
ll cc = n*qpow(s,k)%mod;
ll aa = p*(((s-qpow(s,k+1)%mod)+mod)%mod)%mod*qpow(((1-s)+mod)%mod,mod-2)%mod;//**注意
cout<<(cc+aa)%mod<<endl;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
IOS;
work();
return 0;
}
题解参考代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mod=1e9+7;
ll pow1(ll a,ll b)
{
ll r=1;
while(b)
{
if(b&1)
r=r*a%mod;
a=a*a%mod;
b/=2;
}
return r;
}
int main()
{
int n,m,k,a,b;
scanf("%d%d%d%d%d",&n,&m,&k,&a,&b);
ll p=1LL*a*pow1(b,mod-2)%mod;
ll s=1LL*(n+m)*pow1(n+m+1,mod-2)%mod;
ll ans=1LL*n*pow1(s,k)%mod+p*(s-pow1(s,k+1))%mod*pow1(1-s,mod-2)%mod;
ans=ans%mod+mod; //********注意
printf("%lld\n",ans%mod);
return 0;
}