zoukankan      html  css  js  c++  java
  • hdu4052 Adding New Machine

    Adding New Machine

    Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1555 Accepted Submission(s): 353

    Problem Description

    Incredible Crazily Progressing Company (ICPC) suffered a lot with the low speed of procedure. After investigation, they found that the bottleneck was at Absolutely Crowded Manufactory (ACM). In oder to accelerate the procedure, they bought a new machine for ACM. But a new problem comes, how to place the new machine into ACM?

    ACM is a rectangular factor and can be divided into W * H cells. There are N retangular old machines in ACM and the new machine can not occupy any cell where there is old machines. The new machine needs M consecutive cells. Consecutive cells means some adjacent cells in a line. You are asked to calculate the number of ways to choose the place for the new machine.

    Input

    There are multiple test cases (no more than 50). The first line of each test case contains 4 integers W, H, N, M (1 ≤ W, H ≤ 107, 0 ≤ N ≤ 50000, 1 ≤ M ≤ 1000), indicating the width and the length of the room, the number of old machines and the size of the new machine. Then N lines follow, each of which contains 4 integers Xi1, Yi1, Xi2 and Yi2 (1 ≤ Xi1 ≤ Xi2 ≤ W, 1 ≤ Yi1 ≤ Yi2 ≤ H), indicating the coordinates of the i-th old machine. It is guarantees that no cell is occupied by two old machines.

    Output

    Output the number of ways to choose the cells to place the new machine in one line.

    Sample Input

    3 3 1 2

    2 2 2 2

    3 3 1 3

    2 2 2 2

    2 3 2 2

    1 1 1 1

    2 3 2 3

    Sample Output

    8

    4

    3

    题解

    此题一眼扫描线。
    我们可以先算出所有的方案,之后算出线段的下(右)段在矩阵的方案数,一减就是答案。

    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    #define N 100005
    
    struct Line {
    	int lx, rx, h, flag;
    	Line(int lx, int rx, int h, int flag) :
    		lx(lx), rx(rx), h(h), flag(flag) {}
    	bool operator < (const Line &a) const {
    		return h < a.h;
    	}
    };
    
    struct Point {
    	int x1, y1, x2, y2;
    } p[N];
    
    struct segment {
    	int l, r, flag;
    	long long sum;
    }C[N << 2];
    
    int n;
    long long ans;
    vector<int> a;
    vector<Line> line;
    
    int idx(const int &x) {
    	return lower_bound(a.begin(), a.end(), x) - a.begin();
    }
    
    #define ls u << 1
    #define rs u << 1 | 1
    void pu(int u) {
    	if (C[u].flag)
    		C[u].sum = a[C[u].r] - a[C[u].l];
    	else if (C[u].l + 1 == C[u].r)
    		C[u].sum = 0;
    	else
    		C[u].sum = C[ls].sum + C[rs].sum;
    }
    
    void build(int u, int l, int r) {
    	C[u] = (segment){l, r, 0, 0LL};
    	if (l + 1 == r)
    		return;
    	int mid = (l + r) >> 1;
    	build(ls, l, mid);
    	build(rs, mid, r);
    }
    
    void upd(int u, const int &x, const int &y, const int &v) {
    	if (x <= C[u].l && C[u].r <= y) {
    		C[u].flag += v;
    		pu(u);
    		return;
    	}
    	int mid = (C[u].l + C[u].r) >> 1;
    	if (x < mid) upd(ls, x, y, v);
    	if (mid < y) upd(rs, x, y, v);
    	pu(u);
    }
    
    void solve(bool flag, int w, int h, int m) {
    	a.clear(), line.clear();
    	a.push_back(1);
    	a.push_back(w + 1);
    	int tmp = max(h - m + 2, 1);
    	line.push_back(Line(1, w + 1, tmp, 1));
    	line.push_back(Line(1, w + 1, h + 1, -1));
    	for (int i = 1; i <= n; ++i) {
    		if (!flag) {
    			scanf("%d%d%d%d", &p[i].x1, &p[i].y1, &p[i].x2, &p[i].y2);
    			++p[i].x2, ++p[i].y2;
    		} else {
    			swap(p[i].x1, p[i].y1);
    			swap(p[i].x2, p[i].y2);
    		}
    		tmp = max(p[i].y1 - m + 1, 1);
    		line.push_back(Line(p[i].x1, p[i].x2, tmp, 1));
    		line.push_back(Line(p[i].x1, p[i].x2, p[i].y2, -1));
    		a.push_back(p[i].x1);
    		a.push_back(p[i].x2);
    	}
    	sort(a.begin(), a.end());
    	sort(line.begin(), line.end());
    	a.erase(unique(a.begin(), a.end()), a.end());
    	int sza = a.size(), szline = line.size();
    	build(1, 0, sza);
    	for (int i = 0; i < szline; ++i) {
    		if (i)
    			ans -= C[1].sum * (long long)(line[i].h - line[i - 1].h);
    		upd(1, idx(line[i].lx), idx(line[i].rx), line[i].flag);
    	}
    }
    
    int main() {
    	int w, h, m;
    	while (scanf("%d%d%d%d", &w, &h, &n, &m) == 4) {
    		ans = 2LL * w * h;
    		solve(false, w, h, m);
    		solve(true, h, w, m);
    		if (m == 1)
    			ans >>= 1;
    		printf("%lld
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    二级域名怎么设置阿里云
    Datatable 转换 Dictionary
    mysql查询某一个字段是否包含中文字符
    mysql update select 从查询结果中更新数据
    sql 查找重复数据,并且重复数据有子集
    mysql中key 、primary key 、unique key 与index区别
    mysql添加删除索引,查看某个表的建表语句
    优化你的服务器Apache、MySQL、PHP
    JQUERY多选框,单选框,检查选中的值
    jquery上传插件uploadify使用详解
  • 原文地址:https://www.cnblogs.com/cycleke/p/6423079.html
Copyright © 2011-2022 走看看