BZOJ 4481

思路:

等比数列求和 (无穷项)

+线段树找逆序对

//By SiriusRen
#include <bits/stdc++.h>
const int N=500500;
int n,m,vis[N],now=1;
double p,r[N],tree[N*8],ans;
struct Node{int x,y;}node[N];
bool cmp(Node a,Node b){if(a.x!=b.x)return a.x<b.x;return a.y<b.y;}
void insert(int l,int r,int pos,int num,double wei){
    if(l==r){tree[pos]+=wei;return;}
    int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
    if(mid<num)insert(mid+1,r,rson,num,wei);
    else insert(l,mid,lson,num,wei);
    tree[pos]=tree[lson]+tree[rson];
}
double query(int l,int r,int pos,int L,int R){
    if(L>R)return 0;
    if(l>=L&&r<=R)return tree[pos];
    int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
    if(mid<L)return query(mid+1,r,rson,L,R);
    else if(mid>=R)return query(l,mid,lson,L,R);
    else return query(l,mid,lson,L,R)+query(mid+1,r,rson,L,R);
}
double w(int now,int t){return p*r[t-1]/(1-r[vis[node[now].x]]);}
int main(){
    scanf("%d%d%lf",&n,&m,&p),r[0]=1;
    for(int i=1;i<=500000;i++)r[i]=r[i-1]*(1-p);
    for(int i=1;i<=m;i++)scanf("%d%d",&node[i].x,&node[i].y),vis[node[i].x]++;
    std::sort(node+1,node+1+m,cmp);
    for(int i=1,t=0;i<=n;i++,t=0)while(node[now].x==i)
        t++,insert(1,n,1,node[now].y,w(now,t)),
        ans+=w(now,t)*query(1,n,1,node[now].y+1,n),now++;
    printf("%.2f\n",ans);
}

 

转载于:https://www.cnblogs.com/SiriusRen/p/6919915.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值