zoukankan      html  css  js  c++  java
  • FZU2187 回家种地(矩形面积并)

    矩形面积并(只覆盖一次的面积)的裸题。好久没写代码debug了我太久,太辛酸了。

    #pragma warning(disable:4996)
    #include <iostream>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    
    #define ll long long
    #define maxn 200005
    #define y1 y111
    
    int lf[maxn << 2], rf[maxn << 2];
    int sum[maxn << 2];
    int a[maxn];
    int add[maxn << 2];
    int mi[maxn << 2];
    int ma[maxn << 2];
    
    int n, nSize;
    
    void pushUp(int i)
    {
    	mi[i] = min(mi[i << 1], mi[i << 1 | 1]);
    	ma[i] = max(ma[i << 1], ma[i << 1 | 1]);
    }
    
    void pushDown(int i)
    {
    	if (add[i] != 0){
    		if (lf[i] != rf[i]){
    			add[i << 1] += add[i];
    			add[i << 1 | 1] += add[i];
    			mi[i << 1] += add[i];
    			ma[i << 1] += add[i];
    			mi[i << 1 | 1] += add[i];
    			ma[i << 1 | 1] += add[i];
    			add[i] = 0;
    		}
    	}
    }
    
    void build(int i, int L, int R)
    {
    	lf[i] = L; rf[i] = R; add[i] = mi[i] = ma[i] = 0;
    	if (L == R){
    		sum[i] = a[L];
    		return;
    	}
    	int M = (L + R) >> 1;
    	build(i << 1, L, M);
    	build(i << 1 | 1, M + 1, R);
    	sum[i] = sum[i << 1] + sum[i << 1 | 1];
    }
    
    void upd(int i, int L, int R,int v)
    {
    	if (L == lf[i] && R == rf[i]){
    		add[i] += v;
    		mi[i] += v;
    		ma[i] += v;
    		return;
    	}
    	pushDown(i);
    	int M = (lf[i] + rf[i]) >> 1;
    	if (R <= M){
    		upd(i << 1, L, R,v);
    	}
    	else if (L > M){
    		upd(i << 1 | 1, L, R, v);
    	}
    	else{
    		upd(i << 1, L, M, v);
    		upd(i << 1 | 1, M + 1, R, v);
    	}
    	pushUp(i);
    }
    
    ll query(int i)
    {
    	if (ma[i] <= 0) return 0;
    	if (mi[i] > 1) return 0;
    	if (ma[i] == mi[i] && ma[i] == 1){
    		return sum[i];
    	}
    	pushDown(i);
    	return query(i << 1) + query(i << 1 | 1);
    }
    
    struct Node
    {
    	ll x;
    	ll bg, ed;
    	int v;
    	Node(ll xi, ll bgi, ll edi,int vi) :x(xi), bg(bgi), ed(edi),v(vi){}
    	bool operator < (const Node &b)const{
    		return x == b.x ? v>b.v : x < b.x;
    	}
    };
    vector<Node> vec;
    vector<ll> dis;
    
    int main()
    {
    	int T; cin >> T; int ca = 0;
    	while (T--)
    	{
    		scanf("%d", &n);
    		ll x1, x2, y1, y2;
    		vec.clear();
    		vec.reserve(2 * n + 100);
    		dis.clear();
    		for (int i = 0; i < n; ++i){
    			scanf("%I64d%I64d%I64d%I64d", &x1, &y1, &x2, &y2);
    			vec.push_back(Node(x1, y1, y2,1));
    			vec.push_back(Node(x2, y1, y2,-1));
    			dis.push_back(y1);
    			dis.push_back(y2);
    		}
    		sort(dis.begin(), dis.end());
    		nSize = unique(dis.begin(), dis.end()) - dis.begin();
    		for (int i = 1; i < nSize; ++i){
    			a[i] = dis[i] - dis[i - 1];
    		}
    		for (int i = 0; i < vec.size(); ++i){
    			int lid = lower_bound(dis.begin(), dis.begin()+nSize, vec[i].bg) - dis.begin();
    			int rid = lower_bound(dis.begin(), dis.begin()+nSize, vec[i].ed) - dis.begin();
    			vec[i].bg = lid + 1;
    			vec[i].ed = rid;
    		}
    		sort(vec.begin(), vec.end());
    		build(1, 1, nSize - 1);
    
    		ll ans = 0;
    		ll preLen = 0;
    		ll prex = vec[0].x;
    		for (int i = 0; i < vec.size(); ++i){
    			ll val = vec[i].x;
    			while (i<vec.size()&&vec[i].x == val){
    				upd(1, vec[i].bg, vec[i].ed, vec[i].v);
    				++i;
    			}
    			--i;
    			ans += preLen*(vec[i].x - prex);
    			prex = vec[i].x;
    			preLen = query(1);
    		}
    		printf("Case %d: %I64d
    ", ++ca, ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    shell-变量的数值运算let内置命令
    shell-变量的数值运算符-计算双括号(())的使用
    shell-批量修改文件名及扩展名多案例
    shell-变量的字串应用技术
    一个MVVM前端扩展器
    测试一个mysql 悲观锁
    spring rest项目提示Request method 'PUT' not supported Method Not Allowed 405 错误
    Mysql 使用sql语句添加列,修改列默认值,添加类注释
    理解java泛型中的 上界extend 下界super
    mysql存储过程游标循环装载字符串SQL语句示例
  • 原文地址:https://www.cnblogs.com/chanme/p/4357825.html
Copyright © 2011-2022 走看看