zoukankan      html  css  js  c++  java
  • 洛谷 P2061 [USACO07OPEN]City Horizon S

    Description

    洛谷传送门

    Solution

    我们发现我们是无法快速判断一个区间内我们需要修改哪些数,不需要修改哪些数的。同时我们观察到整个区间初始全为 0.

    所以我们考虑对询问进行排序,按修改高度从低到高排序。

    排完序后,我们对于每一个操作就相当于进行区间修改了(现在区间内的数一定小于等于要修改的数,所以直接区间赋值即可)。

    我们使用线段树进行维护,最后输出根节点的区间和即可。

    另外,这道题还要离散化,把 (1e9) 的坐标范围改到 (8e4)(每次询问有 (l)(r) 两个坐标)。

    而且这道题还要调可恶的边界,因为输入的是轮廓线,这个并不是类似于点权的东西,而是要修改中间的部分,大概类似于开区间?

    建议把区间的 (l)(r) 都存到结构体里,这样就不用调这么多了。

    总之在线段树 (build) 函数中递归调用时要调用 ((l,mid))((mid,r)),简单来说 (mid) 不需要 +1。

    且要判断 (l == r- 1) 时,退出。具体见代码吧。

    最后别忘了开 (long long)

    Code

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #define ls rt << 1
    #define rs rt << 1 | 1
    #define ll long long
    
    using namespace std;
    
    inline ll read(){
    	ll x = 0;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') ch = getchar();
    	while(ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    	return x;
    }
    
    const ll N = 1e5 + 10;
    ll n, ans;
    struct Query{
    	ll l, r;
    	ll h;
    	bool operator < (const Query &b) const{
    		return h < b.h;
    	}
    }q[N];
    ll pos[N << 1], cnt;
    struct Seg_tree{
    	ll l, r, sum, lazy;
    }t[N << 2];
    
    inline void pushup(ll rt){
    	t[rt].sum = t[ls].sum + t[rs].sum;
    }
    
    inline void pushdown(ll rt){
    	if(t[rt].lazy){
    		t[ls].sum = t[rt].lazy * (pos[t[ls].r] - pos[t[ls].l]);
    		t[rs].sum = t[rt].lazy * (pos[t[rs].r] - pos[t[rs].l]);
    		t[ls].lazy = t[rs].lazy = t[rt].lazy;
    		t[rt].lazy = 0;
    	}
    }
    
    inline void build(int l, int r, int rt){
    	t[rt].l = l, t[rt].r = r;
    	if(l == r - 1) return;
    	int mid = (l + r) >> 1;
    	build(l, mid, ls);
    	build(mid, r, rs);
    }
    
    inline void update(ll L, ll R, ll k, ll rt){
    	int l = t[rt].l, r = t[rt].r;
    	if(l > R || r < L) return;
    	if(L <= l && r <= R){
    		t[rt].sum = k * (pos[r] - pos[l]);
    		t[rt].lazy = k;
    		return;
    	}
    	pushdown(rt);
    	ll mid = (l + r) >> 1;
    	if(L < mid) update(L, R, k, ls);
    	if(R > mid) update(L, R, k, rs);
    	pushup(rt);
    }
    
    signed main(){
    	freopen("P2061.in", "r", stdin);
    	freopen("P2061.out", "w", stdout);
    	n = read();
    	for(ll i = 1; i <= n; i++){
    		q[i].l = read(), q[i].r = read(), q[i].h = read();
    		pos[++cnt] = q[i].l, pos[++cnt] = q[i].r;
    	}
    	sort(pos + 1, pos + 1 + cnt);
    	ll tot = unique(pos + 1, pos + 1 + cnt) - pos - 1;
    	for(ll i = 1; i <= n; i++){
    		q[i].l = lower_bound(pos + 1, pos + 1 + tot, q[i].l) - pos;
    		q[i].r = lower_bound(pos + 1, pos + 1 + tot, q[i].r) - pos;
    	}
    	sort(q + 1, q + 1 + n);
    	build(1, tot, 1);
    	for(ll i = 1; i <= n; i++)
    		update(q[i].l, q[i].r, q[i].h, 1);
    	printf("%lld
    ", t[1].sum);
    	return 0;
    }
    

    End

    本文来自博客园,作者:xixike,转载请注明原文链接:https://www.cnblogs.com/xixike/p/15414105.html

  • 相关阅读:
    HDU 5105 Math Problem(BestCoder Round #18)
    HDU 5101 Select(BestCoder Round #17)
    HDU 5100 Chessboard(BestCoder Round #17)(找规律)
    HDU 5087 Revenge of LIS II(BestCoder Round #16)(次长上升子序列)
    HDU 5067 Harry And Dig Machine(BestCoder Round #14)
    HDU 5063 Operation the Sequence(BestCoder Round #13)
    2015ACM/ICPC亚洲区长春站-重现赛 1006 Almost Sorted Array
    2015ACM/ICPC亚洲区沈阳站-重现赛 1004 Pagodas
    Loadrunner 问题总结
    如何解决LodRunner中报错关于Error -10489
  • 原文地址:https://www.cnblogs.com/xixike/p/15414105.html
Copyright © 2011-2022 走看看