zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    PPP点对点协议
    Wireshark包过滤
    asp.net mvc 简单项目框架的搭建过程(一)对Bll层和Dal层进行充分解耦
    sql学习笔记(三)—— 联表查询
    Sql学习笔记(二)—— 条件查询
    bzoj 1696: [Usaco2007 Feb]Building A New Barn新牛舍 ——中位数排序
    汕头市队赛 SRM19 字符题
    bzoj 2037: [Sdoi2008]Sue的小球——dp
    bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形——极角排序
    【BZOJ】3302: [Shoi2005]树的双中心 && 2103: Fire 消防站 && 2447: 消防站
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10591716.html
Copyright © 2011-2022 走看看