1 条题解
-
0
首先,可以利用等比数列求和公式,因为 ,删去分子上的 算出每对男女 在一起的概率。询问时倒叙插入,并用树状数组维护。 比如对于一个女生 ,有 个候选男生编号为 ,那么对于第 个男生, 在一起的概率就是
$$(1-p)^{m-1}\times p+(1-p)^k\times (1-p)^{m-1}\times p+(1-p)^{2k}\times (1-p)^{m-1}\times p+\ldots+(1-p)^{x-1}\times (1-p)^{m-1}\times p$$分别随对应在第 轮、第 轮、第 轮…第 轮选中第 个男生的概率,其中 需要到正无穷。不难发现,其实这是一个以 为首项, 为公比的等比数列,我们要所得就是对这个数列求和。不妨先利用等比数列求和公式:
其中,。瓶颈在于 趋向正无穷,无法精确求出。因为 , 不接近 ,那么当 很大时, 非常接近于 ,因为只需要保留 位小数,不妨把 当做 。那么,答案就是 。
这样我们就求出了每队男女在一起的概率。
至于统计答案,原始想法是枚举每组不稳定的配对关系,算出概率和计可,但是这样只能通过 的数据。我们可以倒序枚举女生,使用树状数组或线段树维护后 个女生与前 个女生配对的概率和。最多操作 次插入 次询问,即可通过全部数据。
#include<bits/stdc++.h> using namespace std; const int N=6e5+7; int lowbit(int x){ return x&(-x); } int n,m,d[N],c[N],pt; double p,pw[N],ans; struct Node{ double a[N]; double sum(int p){ double ans=0; for(;p;p-=lowbit(p)) ans+=a[p]; return ans; } void modefy(int p,double val){ p++; for(;p<=n;p+=lowbit(p)) a[p]+=val; } }t; struct Edge{ int u,v; double p; Edge(){} Edge(int u,int v,double p):u(u),v(v),p(p){}; }e[N]; int main(){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n>>m>>p; for(int i=0,u,v;i<m;i++) cin>>u>>v,u--,v--,d[u]++,e[i]=Edge(u,v,0); sort(e,e+m,[](Edge x,Edge y){if(x.u!=y.u) return x.u<y.u; else return x.v<y.v;}); pw[0]=1.0; for(int i=0;i<n;i++) pw[i+1]=pw[i]*(1-p); for(int i=0,u;i<m;i++){ u=e[i].u; e[i].p=p*pw[c[u]]/(1-pw[d[u]]); c[u]++; }reverse(e,e+m); for(int i=n-1;i>=0;i--){ for(int j=pt;j<m&&e[j].u==i;j++) ans+=t.sum(e[j].v)*e[j].p; for(int j=pt;j<=m&&e[j].u==i;j++) t.modefy(e[j].v,e[j].p),pt=j+1; } cout<<fixed<<setprecision(2)<<ans<<endl; return 0; }管理员大大大辛苦了。
~本蒟蒻的第一篇题解,点个赞再走吧QAQ~
第一篇题解,有勘误请指出qwq
- 1
信息
- ID
- 6146
- 时间
- 2000ms
- 内存
- 500MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者