• 洛谷 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

  • 相关阅读:
    函数式宏定义与普通函数
    linux之sort用法
    HDU 4390 Number Sequence 容斥原理
    HDU 4407 Sum 容斥原理
    HDU 4059 The Boss on Mars 容斥原理
    UVA12653 Buses
    UVA 12651 Triangles
    UVA 10892
    HDU 4292 Food
    HDU 4288 Coder
  • 原文地址:https://www.cnblogs.com/xixike/p/15414105.html
Copyright © 2020-2023  润新知