码迷,mamicode.com
首页 > 其他好文 > 详细

2014-2015 ACM-ICPC, NEERC, Moscow Subregional Contest B - Bring Your Own Bombs 离散化+扫描线+计算期望

时间:2018-12-02 00:38:07      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:continue   def   osc   people   code   its   printf   std   扫描线   

扫描线一边扫一边算期望,细节比较多。

#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 离散化+扫描线+计算期望

标签:continue   def   osc   people   code   its   printf   std   扫描线   

原文地址:https://www.cnblogs.com/CJLHY/p/10051814.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!