• 题解 P3740 【[HAOI2014]贴海报】


    题目描述

    Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论。为了统一管理,城市委员会为选民准备了一个张贴海报的electoral墙。

    张贴规则如下:

    • electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子;

    • 所有张贴的海报的高度必须与electoral墙的高度一致的;

    • 每张海报以“A B”表示,即从第A个格子到第B个格子张贴海报;

    • 后贴的海报可以覆盖前面已贴的海报或部分海报。

    现在请你判断,张贴完所有海报后,在electoral墙上还可以看见多少张海报。

    数据范围:
    n <= 10000000, m <= 1000, A[i], B[i] <= 10000000
    

    主要思路:珂朵莉树

    (珂学盛行!

    我们可以直接用珂朵莉树进行assign操作,然后用一个bool类型的数组做桶,直接进行统计,统计过的就不再统计了。

    code:

    #include <iostream>
    #include <cstdio>
    #include <set>
    #include <stack>
    using namespace std;
    #define go(i, j, n, k) for(int i = j; i <= n; i += k)
    #define mn 100010
    inline int read(){
        int x = 0, f = 1; char ch = getchar();
        while(ch > '9' || ch < '0') { if(ch == '-') f = -f; ch = getchar(); }
        while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
        return x * f;
    }
    
    struct KDL {
    	int l, r; mutable int v;
    	KDL(int _l, int _r = -1, int _v = 0) 
    		: l(_l), r(_r), v(_v) {}
    	bool operator < (const KDL& b) const { return l < b.l; }
    };
    set<KDL> s;
    #define IT set<KDL>::iterator
    int n, m; bool b[mn];
    inline IT split(int pos) {
    	IT it = s.lower_bound(KDL(pos));
    	if(it != s.end() && it->l == pos) return it;
    	--it;
    	int l = it->l, r = it->r, v = it->v;
    	s.erase(it);
    	s.insert(KDL(l, pos - 1, v));
    	return s.insert(KDL(pos, r, v)).first;
    } 
    inline void assign(int l, int r, int val) {
    	IT itr = split(r + 1), itl = split(l);
    	s.erase(itl, itr);
    	s.insert(KDL(l, r, val));
    }
    inline int query(int l, int r) {
    	IT itr = split(r + 1), itl = split(l);
    	int cnt = 0;
    	for(IT it = itl; it != itr; ++it) {
    //		printf("## : %d %d %d
    ", it->l, it->r, it->v);
    		if(!b[it->v] && it->v != 0)
    			b[it->v] = 1, cnt++;
    	}
    	return cnt;
    }
    
    inline void solve() {
    	n = read(), m = read();
    	s.insert(KDL(1, n, 0));
    	go(i, 1, m, 1) {
    		int l = read(), r = read();
    		assign(l, r, i);
    	}
    	cout << query(1, n) << "
    ";
    }
    inline void init() {
    
    }
    int main(){
        solve();
        return 0;
    }
    
  • 相关阅读:
    [日志]一个父亲给儿子的忠告
    [健康]预防手足口病中医有妙方
    [日志]教你怎么用一句话把人弄的又好气又好笑
    [健康]出汗与人健康
    [健康]四招,清除体内“垃圾”
    [健康]生病了绝对不能吃的东西
    [日志]塑造自己品牌的方法
    [健康]肾的保健按摩
    [日志]经典道歉短信
    [日志]几个笑话顿悟人生道理
  • 原文地址:https://www.cnblogs.com/yizimi/p/10582036.html
Copyright © 2020-2023  润新知