列表

详情


NC14627. ChiMu and Inori

描述

众所周知,涯通过祁(Inori)唤醒了真名(最初的“Apocalypse Virus天启病毒”感染者),并且打算将人类带入黑暗的“幻想乡”,世界被病毒感染。天启病毒的关键特征就是长相如同紫水晶一般的晶化体;病人的感染程度越严重,身体里晶化的分布就越多。


虽然ChiMu将Inori救了出来并且阻止了真名的暴走,但是世界还处于危险之中,所以他们又投入到了拯救世界的战斗中。

世界可以被一个坐标表示,x表示横坐标,y表示纵坐标(-100000< x, y < 1000000)。他们发现世界都被不同程度的感染了,但是有很多比较严重的地区需要立即处理。所以ChiMu准备先找到那些受感染严重的地区,计算出他们的大小,在统计的时候,Inori已经先去严重地区吸收病毒了。

最后Inori会将他吸收完病毒的地区告知ChiMu,他们需要你告诉他们剩下的受严重感染地区的大小。

需要统计的地区都是矩形区域。

输入描述

第一行两个整数,n和m,分别表示ChiMu统计的地区数量,Inori已经吸收完病毒的地区数量。(1 <= n, m <= 100000)
接下来n行输入,每行四个实数a, b, c, d,分别表示ChiMu统计的地区左下角和右上角的坐标。(-100000< a, b, c, d < 1000000)
接下来m行输入,每行四个实数e, f, g, h,分别表示Inori已经吸收完病毒的地区左下角和右上角的坐标。(-100000< e ,f, g, h < 1000000)
保证输入样例合法

输出描述

输出有一行,即剩下的受严重感染地区的大小。
数据精确的小数点后两位。

示例1

输入:

2 1
0 0 10 10
9 9 19 19
8 8 10 10

输出:

195.00

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 802ms, 内存消耗: 25596K, 提交时间: 2017-12-18 17:21:02

#include<bits/stdc++.h>
using namespace std;
/*ChiMu Yuan*/
 
const int maxn = 100005;
 
int n, m;
double x[maxn << 1], sumw[maxn << 3];
int add[maxn << 3];
 
struct Width
{
    double l, r, h;
    int stu;
 
    Width(){}
    Width(double a, double b, double c, int d) : l(a), r(b), h(c), stu(d) {}
 
    bool operator < (const Width w) const
    {
        return this->h < w.h;
    }
}width[maxn << 1];
 
void pushup(int id, int l, int r)
{
    if(add[id])
        sumw[id] = x[r - 1] - x[l - 1];
    else if(r - l == 1)
        sumw[id] = 0;
    else
        sumw[id] = sumw[id << 1] + sumw[id << 1 | 1];
    return ;
}
 
void update(int l, int r, int L, int R, int stu, int id)
{
    if(l <= L && R <= r)
    {
        add[id] += stu;
        pushup(id, L, R);
        return ;
    }
    if(R - L <= 1)
        return ;
    int mid = (L + R) >> 1;
    if(r <= mid)
        update(l, r, L, mid, stu, id << 1);
    else if(mid <= l)
        update(l, r, mid, R, stu, id << 1 | 1);
    else
    {
        update(l, r, L, mid, stu, id << 1);
        update(l, r, mid, R, stu, id << 1 | 1);
    }
    pushup(id, L, R);
    return ;
}
 
int main()
{
//    freopen("max.in", "r", stdin);
//    freopen("max.out", "w", stdout);
    double x1, y1, x2, y2;
    double area;
    int cnt, l, r;
    while(~scanf("%d%d", &n, &m))
    {
        memset(sumw, 0, sizeof(sumw));
        memset(add, 0, sizeof(add));
        cnt = area = 0;
        for(int i = 0; i < n; i ++)
        {
            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
            x[cnt] = x1;
            width[cnt ++] = Width(x1, x2, y1, 1);
            x[cnt] = x2;
            width[cnt ++] = Width(x1, x2, y2, -1);
        }
        sort(width, width + cnt);
        sort(x, x + cnt);
        cnt = unique(x, x + cnt) - x;
        for(int i = 0; i < n + n - 1; i ++)
        {
            l = lower_bound(x, x + cnt, width[i].l) - x;
            r = lower_bound(x, x + cnt, width[i].r) - x;
            update(l + 1, r + 1, 1, cnt, width[i].stu, 1);
            area += sumw[1] * (width[i + 1].h - width[i].h);
        }
        memset(sumw, 0, sizeof(sumw));
        memset(add, 0, sizeof(add));
        cnt = 0;
        for(int i = 0; i < m; i ++)
        {
            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
            x[cnt] = x1;
            width[cnt ++] = Width(x1, x2, y1, 1);
            x[cnt] = x2;
            width[cnt ++] = Width(x1, x2, y2, -1);
        }
        sort(width, width + cnt);
        sort(x, x + cnt);
        cnt = unique(x, x + cnt) - x;
        for(int i = 0; i < m + m - 1; i ++)
        {
            l = lower_bound(x, x + cnt, width[i].l) - x;
            r = lower_bound(x, x + cnt, width[i].r) - x;
            update(l + 1, r + 1, 1, cnt, width[i].stu, 1);
            area -= sumw[1] * (width[i + 1].h - width[i].h);
        }
        printf("%.2f\n", area);
    }
    return 0;
}

上一题