题目链接: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;
}