珂朵莉树,真香!
这道题虽然区间特别大,但是对于珂朵莉树来说是小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;
}