zoukankan      html  css  js  c++  java
  • 【51nod 1667】概率好题

    题目

    甲乙进行比赛。
    他们各有k1,k2个集合[Li,Ri]
    每次随机从他们拥有的每个集合中都取出一个数
    S1=sigma甲取出的数,S2同理
    若S1>S2甲胜 若S1=S2平局 否则乙胜
    分别求出甲胜、平局、乙胜的概率。
    (显然这个概率是有理数,记为p/q,则输出答案为(p/q)%(1e9+7))(逆元)
    注意 多组数据

    分析

    考虑甲胜的概率,其他类似,
    (sum x_i>sum y_i),其中(L1[i]<=x_i<=R1[i],L2[i]<=y_i<=R2[i])
    我们设(x_i=L1[i]+x_i,y_i=R2[i]-y_i)
    所以

    [sum L1[i]+x_i>sum R2[i]-y_i ]

    移项

    [sum x_i +sum y_i>sum R2[i]-sum L1[i] ]

    设k

    [sum x_i +sum y_i-1>=sum R2[i]-sum L1[i]+k ]

    然后就可以容斥了,
    枚举至少t个数超出范围,容斥系数为(-1)^k,用插板法求值。

    #include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    const int inf=2147483647;
    const long long mo=1e9+7;
    const int N=10;
    int T,n,m,lim[N],lim1[N],L[N],R[N],L1[N],R1[N];
    long long ans,ny[N*3],an[3];
    using namespace std;
    long long ksm(long long x,int y)
    {
    	long long s=1;
    	for(;y;y>>=1,x=x*x%mo)
    		if(y&1) s=s*x%mo;
    	return s;
    }
    long long C(long long n,long long m)
    {
    	long long s=1;
    	for(long long i=0;i<m;i++) s=s*(n-i)%mo;
    	s=s*ny[m]%mo;
    	return s;
    }
    void dg(int x,int y,int s,int op)
    {
    	if(x>n+m)
    	{
    		if(s<0) return;
    		ans=(ans+(y&1?-1:1)*C(s+n+m+op-1,n+m+op-1)+mo)%mo;
    		return;
    	}
    	dg(x+1,y,s,op),dg(x+1,y+1,x<=n?s-lim[x]-1:s-lim1[x-n]-1,op);
    }
    int main()
    {
    	ny[0]=ny[1]=1;
    	for(int i=2;i<=20;i++) ny[i]=(mo-mo/i)*ny[mo%i]%mo;
    	for(int i=2;i<=20;i++) ny[i]=ny[i-1]*ny[i]%mo;
    	for(scanf("%d",&T);T--;)
    	{
    		scanf("%d",&n);
    		long long num=1;
    		for(int i=1;i<=n;i++) scanf("%d%d",&L[i],&R[i]),lim[i]=R[i]-L[i],num=num*(R[i]-L[i]+1)%mo;
    		scanf("%d",&m);
    		for(int i=1;i<=m;i++) scanf("%d%d",&L1[i],&R1[i]),lim1[i]=R1[i]-L1[i],num=num*(R1[i]-L1[i]+1)%mo;
    		int s=-1;
    		for(int i=1;i<=n;i++) s-=L[i];
    		for(int i=1;i<=m;i++) s+=R1[i];
    		ans=0,dg(1,0,s,1),an[2]=1ll*ans*ksm(num,mo-2)%mo;
    		ans=0,dg(1,0,s+1,0),an[1]=1ll*ans*ksm(num,mo-2)%mo;
    		an[0]=(1-an[1]-an[2]+mo*2)%mo;
    		printf("%lld %lld %lld
    ",an[0],an[1],an[2]);
    	}
    }
    
    
  • 相关阅读:
    access导入报错 请求筛选模块被配置为拒绝超过请求内容长度的请求
    win10装回win7。PE下把原来的系统盘格掉,再安装hdd,重启就好了
    sql语句Order by 报错列名不明确
    C#字符串长度判断
    Struts2中数据封装机制
    Struts2中的页面跳转
    Struts2访问Servlet API的三种方式
    Struts2的动态Action实现
    Struts2基本概念
    javaweb开发之EL表达式
  • 原文地址:https://www.cnblogs.com/chen1352/p/9743443.html
Copyright © 2011-2022 走看看