Gym - 100519 B Bring Your Own Bombs 离散化+二分+思维

题目链接:https://vjudge.net/contest/370255#problem/B

我们考虑每一行每一列会爆炸的概率是多少  显然 对于会爆炸的每一行 位于该行的矩形的长都会爆炸  对于会爆炸的每一列 位于该列的矩形的宽都会爆炸  但是对于 行列都爆炸的但我 我们显然重复计算了 所以要容斥一下

#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 1e5+10;
int x4[N],x2[N],x3[N];
int y4[N],y2[N],y3[N];
double px[N],py[N],dx[N],dy[N],fx[N],fy[N];
int cx[N],cy[N],ctx,cty;
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= n; i++){
		scanf("%d%d%d%d",&x4[i],&y4[i],&x2[i],&y2[i]);
	}
	for(int i = 1; i <= m; i++){
		scanf("%d%d",&x3[i],&y3[i]);
		cx[++ctx]=x3[i],cy[++cty]=y3[i];
		scanf("%lf%lf",&fy[i],&fx[i]);
		dx[i]=dy[i]=1;
	}
	sort(cx+1,cx+1+ctx);sort(cy+1,cy+1+cty);
	ctx=unique(cx+1,cx+1+ctx)-cx-1;
	cty=unique(cy+1,cy+1+cty)-cy-1;
	for(int i = 1; i <= m; i++){//计算每行每列爆炸的概率
		int x = lower_bound(cx+1,cx+1+ctx,x3[i])-cx;
		dx[x]*=(100-fx[i])/100.00;
		int y = lower_bound(cy+1,cy+1+cty,y3[i])-cy;
		dy[y]*=(100-fy[i])/100.00;
	}
//对这些概率求前缀和
	for(int i = 1; i <= ctx; i++) dx[i]=1-dx[i],px[i]=px[i-1]+dx[i];
	for(int i = 1; i <= cty; i++) dy[i]=1-dy[i],py[i]=py[i-1]+dy[i];
	double ans = 0;
	for(int i = 1; i <= n; i++){
		int l1=lower_bound(cx+1,cx+1+ctx,x4[i])-cx;
		int r1=upper_bound(cx+1,cx+1+ctx,x2[i])-cx-1;
		int l2=lower_bound(cy+1,cy+1+cty,y4[i])-cy;
		int r2=upper_bound(cy+1,cy+1+cty,y2[i])-cy-1;
		double p1=px[r1]-px[l1-1],p2=py[r2]-py[l2-1];
		ans+=p1*(y2[i]-y4[i]+1)+p2*(x2[i]-x4[i]+1)-p1*p2;//p1*p2是容斥
	}
	printf("%.8f\n",ans);
	return 0;
} 
原创文章 85 获赞 103 访问量 2480

猜你喜欢

转载自blog.csdn.net/weixin_43824564/article/details/105907107
今日推荐