NC20221. [JSOI2015]非诚勿扰
描述
输入描述
输入第一行包含2个自然数N,M,表示有N个女性和N个男性,以及所有女性的“如意郎君列表”长度之和是M。
接下来一行一个实数P,为女性接受男性的概率。
接下来M行,每行包含两个整数a,b,表示男性b在女性a的“如意郎君列表” 中。
输入保证每个女性的“如意郎君列表”中的男性出现切仅出现一次。
1 ≤ N,M ≤ 500,000,0.4 ≤ P < 0.6
输出描述
输出1行,包含一个实数,四舍五入后保留到小数点后2位,表示不稳定因素的期望数目。
示例1
输入:
5 5 0.5 5 1 3 2 2 2 2 1 3 1
输出:
0.89
C++11(clang++ 3.9) 解法, 执行用时: 224ms, 内存消耗: 20060K, 提交时间: 2019-03-09 18:22:15
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define ld long double int n,m,now; ld p,c[500001],ans,r,w,gl[500001]; struct node{ int x,y; }a[500001]; bool operator < (node u,node v) { return u.x==v.x ? u.y<v.y:u.x<v.x; } int read() { int x=0,f=1;char ch=getchar(); while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();} while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } void add(int u,ld v) { for(;u<=n;u+=u&(-u)) c[u]+=v; } ld cal(int u) { ld now=0; for(;u;u-=u&(-u)) now+=c[u]; return now; } int main() { n=read();m=read();cin>>p; for(int i=1;i<=m;i++) a[i].x=read(),a[i].y=read(); sort(a+1,a+m+1); for(int i=1;i<=m;i++) { if(now!=a[i].x) { for(register int j=i-1;j && a[j].x==now;j--) add(a[j].y,gl[j]); now=a[i].x;r=w=1; for(register int j=0;a[i+j].x==now;j++,w*=(1-p)); w=1.0-w; } gl[i]=r*p/w;r*=(1-p); ans+=gl[i]*(cal(n)-cal(a[i].y)); } printf("%.2lf\n",(double)ans); return 0; }