2014-2015 ACM-ICPC, NEERC, Moscow Subregional Contest B - Bring Your Own Bombs 離散化+掃描線+計算期望
阿新 • • 發佈:2018-12-02
lower 細節 main fin cto spa nal chan acm-icpc
掃描線一邊掃一邊算期望,細節比較多。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define PLI pair<LL, int> #define PLL pair<LL, LL> #define ull unsigned long long using namespace std; const int N = 4e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; int n, m, tot, X[N], cntx, Y[N], cnty, zero[N], zero2[N], people, people2; double val[N], val2[N], sum[N], fact[N], fact2[N], ret, ans; struct qus { int y, x1, x2, op; } a[N];struct Point { int x, y; double p[3]; } b[N]; struct Bit { int a[N]; void modify(int x, int v) { for(int i = x; i < N; i+=i&-i) a[i] += v; } int sum(int x) { int ans = 0; for(int i = x; i; i-=i&-i) ans += a[i];return ans; } } bit; vector<Point> point[N]; vector<PII> in[N], out[N]; inline void changed(int x, double p) { if(zero[x] > 1) return; if(p < eps) fact[x] = val[x]; else fact[x] /= p; } inline void changem(int x, double p) { fact[x] *= p; } inline void changed2(int y, double p) { if(zero2[y] > 1) return; if(p < eps) fact2[y] = val2[y]; else fact2[y] /= p; } inline void changem2(int x, double p) { fact2[x] *= p; } int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { int x1, y1, x2, y2; scanf("%d%d%d%d", &x1, &y1, &x2, &y2); a[++tot] = qus{y1, x1, x2, 1}; a[++tot] = qus{y2, x1, x2, -1}; X[++cntx] = x1; X[++cntx] = x2; Y[++cnty] = y1; Y[++cnty] = y2; } for(int i = 1; i <= m; i++) { scanf("%d%d%lf%lf", &b[i].x, &b[i].y, &b[i].p[0], &b[i].p[1]); b[i].p[0]/=100, b[i].p[1] /= 100, b[i].p[2] = 1 - b[i].p[1] - b[i].p[0]; X[++cntx] = b[i].x; Y[++cnty] = b[i].y; } sort(X+1, X+1+cntx); sort(Y+1, Y+1+cnty); cntx = unique(X+1, X+1+cntx)-X-1; cnty = unique(Y+1, Y+1+cnty)-Y-1; for(int i = 1; i <= cntx; i++) val[i] = 1.0; for(int i = 1; i <= cnty; i++) val2[i] = 1.0; for(int i = 1; i <= tot; i++) { a[i].y = lower_bound(Y+1, Y+1+cnty, a[i].y)-Y; a[i].x1 = lower_bound(X+1, X+1+cntx, a[i].x1)-X; a[i].x2 = lower_bound(X+1, X+1+cntx, a[i].x2)-X; if(a[i].op == 1) in[a[i].y].push_back(mk(a[i].x1, a[i].x2)); else out[a[i].y].push_back(mk(a[i].x1, a[i].x2)); } for(int i = 1; i <= m; i++) { b[i].x = lower_bound(X+1, X+1+cntx, b[i].x)-X; b[i].y = lower_bound(Y+1, Y+1+cnty, b[i].y)-Y; if(1-b[i].p[1] > eps) val[b[i].x] *= (1-b[i].p[1]); else zero[b[i].x]++; if(1-b[i].p[0] > eps) val2[b[i].y] *= (1-b[i].p[0]); else zero2[b[i].y]++; point[b[i].y].push_back(b[i]); } for(int i = 1; i <= cntx; i++) { if(zero[i]) fact[i] = 0; else fact[i] = val[i]; sum[i] = sum[i-1] + fact[i]; } for(int i = 1; i <= cnty; i++) { if(zero2[i]) fact2[i] = 0; else fact2[i] = val2[i]; } for(int i = 1; i <= cnty; i++) { ans += (Y[i]-Y[i-1]-1)*(people-ret); for(PII sgm : in[i]) { people += sgm.se-sgm.fi+1; people2 += X[sgm.se]-X[sgm.fi]+1-(sgm.se-sgm.fi+1); ret += sum[sgm.se] - sum[sgm.fi-1]; bit.modify(sgm.fi, 1); bit.modify(sgm.se+1, -1); } double res1 = ret, res2 = 0; for(Point p : point[i]) { if(!bit.sum(p.x)) continue; res1 -= fact[p.x]; changed(p.x, 1-p.p[1]); changed2(p.y, 1-p.p[0]); res2 += fact[p.x]*fact2[p.y]*p.p[2]; changem(p.x, 1-p.p[1]); changem2(p.y, 1-p.p[0]); } ans += people - (fact2[i]*res1 + res2) + people2*(1-fact2[i]); for(PII sgm : out[i]) { people -= sgm.se-sgm.fi+1; people2 -= X[sgm.se]-X[sgm.fi]+1-(sgm.se-sgm.fi+1); ret -= sum[sgm.se] - sum[sgm.fi-1]; bit.modify(sgm.fi, -1); bit.modify(sgm.se+1, 1); } } printf("%.12f\n", ans); return 0; } /* */
2014-2015 ACM-ICPC, NEERC, Moscow Subregional Contest B - Bring Your Own Bombs 離散化+掃描線+計算期望