• 2014-2015 ACM-ICPC, NEERC, Moscow Subregional Contest B


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

    #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
    ", ans);
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    SQL Server 2008 R2英文版安装图解
    浅析在C#里面抛出SAP里面自定义的异常信息
    JavaScript中的函数基础
    《冷眼看IT》读书笔记IT将成为服务行业
    JavaScript入门
    IT成为第五个服务业
    JavaScript中匿名函数的困惑
    自定义的html radio button的样式
    探索客户端JavaScript
    JavScript中的循环
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10051814.html
Copyright © 2020-2023  润新知