CF915E Physical Education Lessons

珂朵莉树,真香!

这道题虽然区间特别大,但是对于珂朵莉树来说是小case。因为只要考虑连续的数字就可以了。

初始化就直接建\([1,n]\)\(1\),然后改区间推成0的就退成0,推成1的就推成1就可以了。

但是有一个小问题:你暴力地对整颗珂朵莉树区算那个sum,你会T掉。

解决方法很简单:在每一次assign操作的时候改一改就完事了。

话说两个split的顺序还有讲究呢,要r+1在前,l在后。

我永远喜欢珂朵莉!!!

代码:

#include<cstdio>
#include<set>
#include<algorithm>
const int maxn = 1e9 + 5;
int n, m, ans;
struct Nodes
{
    int l, r;
    mutable bool v;
    Nodes(int l, int r = -1, bool v = false): l(l), r(r), v(v){}
    bool operator < (const Nodes &rhs) const
    {
        return l < rhs.l;
    }
};
std::set<Nodes> chotholly;
#define IT std::set<Nodes>::iterator
IT split(int pos)
{
    IT it = chotholly.lower_bound(Nodes(pos));
    if(it != chotholly.end() && it->l == pos) return it;
    --it;
    int l = it->l, r = it->r;
    bool v = it->v;
    chotholly.erase(it);
    chotholly.insert(Nodes(l, pos - 1, v));
    return chotholly.insert(Nodes(pos, r, v)).first;
}
void assign(int l, int r, bool x)
{
    IT itr = split(r + 1), itl = split(l);
    for(IT it = itl; it != itr; ++it)
    {
        if(it->v) ans -= (it->r - it->l + 1);
    }
    chotholly.erase(itl, itr);
    chotholly.insert(Nodes(l, r, x));
    if(x) ans += (r - l + 1);
}
int read()
{
    int ans = 0, s = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0'){ if(ch == '-') s = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') ans = (ans << 3) + (ans << 1) + ch - '0', ch = getchar();
    return s * ans;
}
int main()
{
    n = read(), m = read();
    chotholly.insert(Nodes(1, n, true));
    chotholly.insert(Nodes(n + 1, n + 1, false));
    ans = n;
    while(m--)
    {
        int l = read(), r = read(), k = read();
        if(k == 1) assign(l, r, 0);
        else if(k == 2) assign(l, r, 1);
        printf("%d\n", ans);
    }
    
    return 0;
}
posted @ 2018-10-25 22:10  Garen-Wang  阅读(162)  评论(0编辑  收藏  举报