基准时间限制:4 秒 空间限制:131072 KB 分值: 640 
甲乙进行比赛。

他们各有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

数学问题 容斥

$[L_i,R_i]$的限制看上去很迷,不怎么好做。

如果能去掉下界的话,原问题似乎可以转化成容斥求方程解的个数的问题。

我们来试试去掉下界:

设前ki个集合为 $R_i - x_i$,后ki个集合为 $ L_i + x_i $

此时x的取值范围是 $[0,R_i - L_i]$

那么甲赢乙的情况需要满足的条件是:

$$\sum_{i=1}^{k_1} R_i-x_i > \sum_{j=1}^{k_2} L_j+y_j $$

$$\sum_{i=1}^{k_1} x_i + \sum_{j=1}^{k_2} y_j< \sum_{i=1}^{k_1} R_i -\sum_{j=1}^{k_2} L_j $$

我们惊喜地发现右边是常数,那么可以用组合数+容斥算方程解的个数辣

甲乙平手的情况,只需要把上面的大于换成等于号即可。

乙赢甲的情况,可以把上式取负计算解个数,也可以直接用总方案数减去前两问方案数。

总方案数当然就是所有的$R_i-L_i+1$的乘积

答案当然就是满足条件的方案数除以总方案数

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define LL long long
using namespace std;
const int mod=1e9+;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*-''+ch;ch=getchar();}
return x*f;
}
int ksm(int a,int k){
int res=;
while(k){
if(k&)res=(LL)res*a%mod;
a=(LL)a*a%mod;
k>>=;
}
return res;
}
int fac[mxn*],inv[mxn*];
void init(){
int ed=mxn*;
fac[]=fac[]=;inv[]=inv[]=;
for(int i=;i<ed;i++){
fac[i]=(LL)fac[i-]*i%mod;
inv[i]=((-mod/i*(LL)inv[mod%i]%mod)+mod)%mod;
}
return;
}
int C(int n,int m){
if(m>n || n<)return ;
// return (LL)fac[n]*inv[m]%mod*inv[n-m]%mod;
int res=;
for(int i=;i<=m;i++){
res=(LL)res*(n-m+i)%mod;
}
for(int i=;i<=m;i++){
res=(LL)res*ksm(i,mod-)%mod;
}
return res;
}
int ans1,ans2,ans3;//1 2 0
int n,smm,lower=;
int k1,k2,L[mxn],R[mxn];
void calc(int pos,int f,int x){
if(pos>n){
ans1=((LL)ans1+f*C(smm-x+n-,n))%mod;
// printf("%d %d\n",smm-x+n-1,n);
ans2=((LL)ans2+f*C(smm-x+n-,n-))%mod;
// printf("%d\n",ans1);
return;
}
calc(pos+,-f,x+R[pos]-L[pos]+);
calc(pos+,f,x);
return;
}
int main(){
int i,j;
// init();
int T=read();
while(T--){
ans1=ans2=ans3=;
lower=;smm=;
k1=read();
for(i=;i<=k1;i++){
L[i]=read();R[i]=read();
smm+=R[i];
}
k2=read();
for(i=;i<=k2;i++){
L[i+k1]=read();R[i+k1]=read();
smm-=L[i+k1];
}
n=k1+k2;
for(i=;i<=n;i++)lower=(LL)lower*(R[i]-L[i]+)%mod;
calc(,,);
int INV=ksm(lower,mod-);
ans3=((LL)lower-ans1-ans2)*INV%mod;
ans1=(LL)ans1*INV%mod;
ans2=(LL)ans2*INV%mod;
ans1=(ans1+mod)%mod;
ans2=(ans2+mod)%mod;
ans3=(ans3+mod)%mod;
printf("%d %d %d\n",ans1,ans2,ans3);
}
return ;
}

设前ki个集合为 $R_i - x_i$,后ki个集合为 $ L_i + x_i $此时x的取值范围是 $[0,R_i - L_i]$那么甲赢乙的情况需要满足的条件是:$$\sum_{i=1}^{k_1} R_i-x_i > \sum_{j=1}^{k_2} L_j+y_j $$$$\sum_{i=1}^{k_1} x_i + \sum_{j=1}^{k_2} y_j< \sum_{i=1}^{k_1} R_i -\sum_{j=1}^{k_2} L_j $$我们惊喜地发现右边是常数,那么可以用组合数+容斥算方程解的个数辣甲乙平手的情况,只需要把上面的大于换成等于号即可。乙赢甲的情况,可以把上式取负计算解个数,也可以直接用总方案数减去前两问方案数。总方案数当然就是所有的$R_i-L_i+1$的乘积

51nod1667 概率好题的更多相关文章

  1. 51nod 1667 概率好题

    Description: 甲乙进行比赛. 他们各有k1,k2个集合[Li,Ri] 每次随机从他们拥有的每个集合中都取出一个数 S1=sigma甲取出的数,S2同理 若S1>S2甲胜 若S1=S2 ...

  2. 【CF913F】Strongly Connected Tournament 概率神题

    [CF913F]Strongly Connected Tournament 题意:有n个人进行如下锦标赛: 1.所有人都和所有其他的人进行一场比赛,其中标号为i的人打赢标号为j的人(i<j)的概 ...

  3. 概率好题 Light OJ 1027

    题目大意:你在迷宫里,有n扇门,每个门有一个val,这个val可正可负,每次通过一扇门需要abs(x)分钟,如果这个门的val是正的,那么就直接出了迷宫,否则回到原地,问出去迷宫的期望是多少? 思路: ...

  4. A - Arcade Game Gym - 100814A (概率思维题)

    题目链接:https://cn.vjudge.net/contest/285964#problem/A 题目大意:每一次给你你一个数,然后对于每一次操作,可以将当前的数的每一位互换,如果互换后的数小于 ...

  5. 51Nod 1667 概率好题 - 容斥原理

    题目传送门 无障碍通道 有障碍通道 题目大意 若$L_{i}\leqslant x_{i} \leqslant R_{i}$,求$\sum x_{i} = 0$以及$\sum x_{i} < 0 ...

  6. LightOJ 1218 概率水题(几何分布)

    题意:给你一个n面骰子,问你投出所有面需要的次数的期望值是多少. 题解:放在过去估计秒解,结果现在自己想好久,还查了下,有人用极限证明...实际上仔细想想这种情况投出与前面不一样的概率p的倒数就是次数 ...

  7. 集训第六周 数学概念与方法 概率 N题

    N - 概率 Time Limit:4000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status ...

  8. 集训第六周 数学概念与方法 概率 F题

    Submit Status Description Sometimes some mathematical results are hard to believe. One of the common ...

  9. 【51nod 1667】概率好题

    题目 甲乙进行比赛. 他们各有k1,k2个集合[Li,Ri] 每次随机从他们拥有的每个集合中都取出一个数 S1=sigma甲取出的数,S2同理 若S1>S2甲胜 若S1=S2平局 否则乙胜 分别 ...

随机推荐

  1. BluetoothClass详解

    一. BluetoothClass简介 1. 继承关系 public final class BluetoothClass extends Object implements Parcelable 该 ...

  2. Java中I/O流之数据流

    Java 中的数据流: 对于某问题:将一个 long 类型的数据写到文件中,有办法吗?    转字符串 → 通过 getbytes() 写进去,费劲,而且在此过程中 long 类型的数需要不断地转换. ...

  3. PCA算法理解及代码实现

    github:PCA代码实现.PCA应用 本文算法均使用python3实现 1. 数据降维   在实际生产生活中,我们所获得的数据集在特征上往往具有很高的维度,对高维度的数据进行处理时消耗的时间很大, ...

  4. Spring Boot(二)配置分析

    回顾一下采用SSM开发项目时,项目中会存在多个配置文件,比如web.xml,配置Spring相关的applicationContext-springmvc.xml, applicationContex ...

  5. 织梦dede:list标签在列表页同一文章显示两次的解决方法

    在列表页用{dede:list}标签调用文章的时候出现了同一篇文章显示两次的问题,经过一天的奋战最后终于解决了,下面CMS集中营站长简单说下我的解决过程来供各位学友参考:1.怀疑是不是每次添加都会自动 ...

  6. [剑指Offer] 39.平衡二叉树

    题目描述 输入一棵二叉树,判断该二叉树是否是平衡二叉树. class Solution { public: int Get_Height(TreeNode* root) { if(root == NU ...

  7. SSM整合步骤

    第一步:mybatis和spring整合 mybatis-spring-1.2.2:是mybatis官方出的包: mybatis的包: mybatis和spring的整合包: spring及sprin ...

  8. el语句 的 变量只能从域对象中获取 所以需要先添加到域对象

    el语句 的 变量只能从域对象中获取 所以需要先添加到域对象

  9. I/O复用----select

    2018-07-31 (星期二)I/O复用:    一个应用程序通常需要服务一个以上的文件描述符.    例如stdin,stdout,进程间通信以及若干文件进行I/O,如果不借助线程的话,(线程通常 ...

  10. BZOJ4589:Hard Nim——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4589 Claris和NanoApe在玩石子游戏,他们有n堆石子,规则如下: 1. Claris和N ...