您的位置:首页 > 其它

51nod 1667 概率好题

2017-06-21 10:28 134 查看
甲乙进行比赛。

他们各有k1,k2个集合[Li,Ri]
每次随机从他们拥有的每个集合中都取出一个数
S1=sigma甲取出的数,S2同理
若S1>S2甲胜 若S1=S2平局 否则乙胜
分别求出甲胜、平局、乙胜的概率。 (显然这个概率是有理数,记为p/q,则输出答案为(p/q)%(1e9+7))(逆元)
注意 多组数据
Input
一个数,数据组数(T<=5)
对于每组数据 输入顺序为
 k1 L1 R1...Lk1 Rk1
k2 L1 R1...Lk2 Rk2
(k1,k2<=8,1<=L<=R<=10^7)

Output
甲胜、平局、乙胜的概率。
(显然这个概率是有理数,记为p/q,则输出答案为(p/q)%(1e9+7))(逆元)

Input示例
1
1 1 2
1 1 4

Output示例
125000001 250000002 625000005


[分析]

概率好题

容斥原理+脑子

[代码]

#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mod=1e9+7;
const int mxn=10;
int L[mxn],R[mxn];
int T,n,m,t,sum,ans1,ans2,ans3;
inline int ksm(int x,int k)
{
if(k==1) return x;
int tmp=ksm(x,k>>1);
if(k&1) return (ll)tmp*tmp%mod*x%mod;
else return (ll)tmp*tmp%mod;
}
inline ll C(int n,int m)
{
if(n<m) return 0;
int i,j,res=1;
fo(i,n-m+1,n) res=(ll)res*i%mod;
fo(i,1,m) res=(ll)res*ksm(i,mod-2)%mod;
return res;
}
inline void dfs(int w,int f,int x)
{
if(w>n)
{
ans1=(ans1+f*C(sum-x+n-1,n))%mod;ans1=(ans1+mod)%mod;
ans2=(ans2+f*C(sum-x+n-1,n-1))%mod;ans2=(ans2+mod)%mod;
return;
}
dfs(w+1,f,x);
dfs(w+1,-f,x+R[w]-L[w]+1);
}
int main()
{
int i,j;
scanf("%d",&T);
while(T--)
{
sum=ans1=ans2=ans3=0,t=1;
scanf("%d",&n);
fo(i,1,n)
{
scanf("%d%d",&L[i],&R[i]);
sum+=R[i];
}
scanf("%d",&m);
fo(i,n+1,n+m)
{
scanf("%d%d",&L[i],&R[i]);
sum-=L[i];
}
n+=m;
fo(i,1,n) t=(ll)t*(R[i]-L[i]+1)%mod;
dfs(1,1,0);ans3=(t-ans1-ans2)%mod;ans3=(ans3+mod)%mod;
ans1=(ll)ans1*ksm(t,mod-2)%mod;
ans2=(ll)ans2*ksm(t,mod-2)%mod;
ans3=(ll)ans3*ksm(t,mod-2)%mod;
printf("%d %d %d\n",ans1,ans2,ans3);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: