# 江西CCPC省赛-Rng(概率+逆元)

江西CCPC省赛-Rng(概率+逆元)

题意:

  • 给出一个n,在[1,n]之间选一个R1,在[1,R1]之间选一个L1,得到区间[L1,R1],同理获取区间[L2,R2],问两个区间相交的概率对1e9+7取模。

思路1:

  • 分情况讨论,条件概率的使用
    在这里插入图片描述
    AcCode
#include <bits/stdc++.h>
using namespace std;
#define fre freopen("C:\\Users\\22765\\Desktop\\in.txt","r",stdin);
#define ms(a) memset((a),0,sizeof(a))
#define re(i,a,b) for(int (i)=(a);(i)<(b);(i)++)
#define sf(x) scanf("%d",&(x))
#define rg register
#define il inline
typedef long long LL;
const int inf=(0x7f7f7f7f);
const int maxn=1e6+5;
const int mod=1e9+7;

LL inv[maxn];
LL sum_inv[maxn];

//线性递推求逆元
void init(){
    inv[1]=1;
    re(i,2,maxn){
        inv[i]=((mod-mod/i)*inv[mod%i])%mod;
    }   
}

//逆元前缀和处理
void getsum() {
    re(i,1,maxn){
        sum_inv[i]=sum_inv[i-1]+inv[i]%mod;
    }   
}

int main(){
    LL n;
    init();getsum();
//  for(int i=1;i<=20;i++)cout<<inv[i]<<" "<<sum_inv[i]<<endl;
    while(cin>>n){
        LL ans=(n+3)*inv[n]%mod*inv[4]%mod;
        re(i,1,n+1){
            ans=ans+i*(sum_inv[n]-sum_inv[i]+mod)%mod*inv[n]%mod*inv[n]%mod;
            ans%=mod;
        }
        cout<<ans<<endl;
    }
    return 0;
}

思路2:

  • 直接求相交比较麻烦,可以通过先求不相交,再用1减去即可,正难则反定理,比上一种方法简单很多(逃
    在这里插入图片描述
    其中分子为不相交时可能出现的位置,分母为两个端点在没有限制情况下所有可能出现的位置。

AcCode:

#include <bits/stdc++.h>
using namespace std;
#define fre freopen("C:\\Users\\22765\\Desktop\\in.txt","r",stdin);
#define ms(a) memset((a),0,sizeof(a))
#define re(i,a,b) for(int (i)=(a);(i)<(b);(i)++)
#define sf(x) scanf("%d",&(x))
#define rg register
#define il inline
typedef long long LL;
const int inf=(0x7f7f7f7f);
const int maxn=3000;
LL q=1000000007;
LL qpow(LL a,LL b){
    LL ans=1;
    a%=q;
    while(b){
        if(b&1)ans=ans*a%q;
        b>>=1;
        a=a*a%q;
    } 
    return ans;
}
LL inv(LL a){
    if(a==1)return 1;
    return qpow(a,q-2);
}

int main(){
    LL n;
    while(cin>>n){
        cout<<(n+1)*inv(2*n)%q<<endl; 
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sstealer/p/11250734.html