【JSOI2015】【JZOJ 4063】非诚勿扰

37 篇文章 0 订阅
13 篇文章 0 订阅

Description

这里写图片描述
这里写图片描述

Analysis

对于每个女性,开一个vector记录可选的男性
扫一遍,可以O(1)算出该女性选择第i个男性的期望(推推公式发现是等比数列)
有了这个就好办啦,按女性为第一关键字男性第二关键字排个序,用树状数组记录下前面的女性选择比当前大的男性的概率和
O(nlogn)
在算期望时涉及除法运算,精度误差较大,所以要开long double或者强行不用等比数列直接乘多几次

Code

#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long double db;
const int N=500005;
db P,BIT[N];
int n,m,num;
vector<int> a[N];
struct node
{
    int x,y;
    db p;
}b[N];
bool cmp(node a,node b)
{
    return a.x<b.x || a.x==b.x && a.y<b.y;
}
int lowbit(int x)
{
    return x&-x;
}
db get(int x)
{
    db t=0;
    for(int i=x;i;i-=lowbit(i)) t+=BIT[i];
    return t;
}
void add(int x,db y)
{
    for(int i=x;i<=n;i+=lowbit(i)) BIT[i]+=y;
}
int main()
{
    freopen("cross.in","r",stdin);
    freopen("cross.out","w",stdout);
    int x,y;
    scanf("%d %d %Lf",&n,&m,&P);
    fo(i,1,m)
    {
        scanf("%d %d",&x,&y);
        a[x].push_back(y);
    }
    fo(i,1,n)
    {
        int s=a[i].size();
        sort(a[i].begin(),a[i].end());
        fo(id,0,s-1)
        {
            int j=a[i][id];
            b[++num].x=i,b[num].y=j;
            db t1=pow(1-P,id)*P,t2=1-pow(1-P,s);
            b[num].p=t1/t2;
        }
    }
    sort(b+1,b+num+1,cmp);
    db ans=0;
    fo(i,1,num)
    {
        db t=get(n)-get(b[i].y);
        ans+=b[i].p*t;
        add(b[i].y,b[i].p);
    }
    printf("%.2Lf",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值