• 51nod 小朋友的笑话


    链接

    分析:

      每次操作把以前没有出现这个数的设为1,有这个数的设为0。首先将当前区间设为1,考虑有set维护这个颜色出现的区间,然后把所有与当前区间相交的拿出来,修改为0。

      复杂度?每次操作的线段只会加入到一次set中,从set中取出一次,只会修改一次,然后就合并成大的了,每次操作也只会加入一条线段。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<cctype>
    #include<set>
    #include<queue>
    #include<vector>
    #include<map>
    #include<bitset>
    #define pa pair<int,int>
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 100005;
    set< pa > s[N];
    int n;
    
    struct SegmentTree{
        int sum[N << 2], tag[N << 2], n;
        SegmentTree() { memset(tag, -1, sizeof(tag)); }
        void pushdown(int rt,int len) {
            tag[rt << 1] = tag[rt], tag[rt << 1 | 1] = tag[rt];
            sum[rt << 1] = tag[rt] * (len - len / 2);
            sum[rt << 1 | 1] = tag[rt] * (len / 2);
            tag[rt] = -1;
        }
        void update(int l,int r,int rt,int L,int R,int v) {
            if (L > R) return ;
            if (L <= l && r <= R) { tag[rt] = v, sum[rt] = v * (r - l + 1); return ; }
            if (~tag[rt]) pushdown(rt, r - l + 1);
            int mid = (l + r) >> 1;
            if (L <= mid) update(l, mid, rt << 1, L, R, v);
            if (R > mid) update(mid + 1, r, rt << 1 | 1, L, R, v);
            sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
        }
        int query(int l,int r,int rt,int L,int R) {
            if (L <= l && r <= R) return sum[rt];
            if (~tag[rt]) pushdown(rt, r - l + 1);
            int mid = (l + r) >> 1, res = 0;
            if (L <= mid) res = query(l, mid, rt << 1, L, R);
            if (R > mid) res += query(mid + 1, r, rt << 1 | 1, L, R);
            return res;
        }
    }T;
    void Insert() {
        int x = read(), y = read(), k = read(), l = max(1, x - k), r = min(n, x + k), nowl = l, nowr = r;
        if (s[y].empty()) {
            T.update(1, n, 1, l, r, 1);
            s[y].insert(pa(l, r)); return ; 
        }
        set< pa > :: iterator it = s[y].lower_bound(pa(l, 0));
        set< pa > :: iterator pre = it;
        
        if (it != s[y].begin()) {
            pre --;
            if (pre->second >= l) it = pre;
        }
        if (it == s[y].end() || (it->first) > r) {
            T.update(1, n, 1, l, r, 1);
            s[y].insert(pa(l, r)); return ;
        }
        nowl = min(nowl, it->first);
        T.update(1, n, 1, l, r, 1);
        while (it != s[y].end() && (it->first) <= r) {
            T.update(1, n, 1, max(l, it->first), min(r, it->second), 0);
            nowr = max(nowr, it->second);
            pre = it; it ++; s[y].erase(pre);
        }
        s[y].insert(pa(nowl, nowr));    
    }
    void query() {
        int l = read(), r = read();
        printf("%d
    ", T.query(1, n, 1, l, r));
    }
    int main() {
        n = read();int m = read();
        for (int i = 1; i <= m; ++i) {
            if (read() == 1) Insert();
            else query();        
        }
        return 0;
    }
  • 相关阅读:
    FIFO深度计算
    php学习笔记--函数
    php学习笔记--类型转换
    php学习笔记--变量与常量
    css之伪对象-webkit-scrollbar
    8大排序算法
    正则表达式
    SDC Tcl package of Timequest
    面试经历之今日头条
    《Linux高性能服务器编程》学习总结(十三)——多进程编程
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10591716.html
Copyright © 2020-2023  润新知