暴力数据结构牛逼!!!
这道题给你好多的01串,还有好多的区间统一赋值。
没错,你想到了什么?
珂朵莉树!
所以你就可以用珂朵莉树很轻松地水过这道题了!
唯一要注意的是split的顺序。必须先split右边的,再split左边的。
原因是先split左边的时候,可能会因为split右边而导致原迭代器被删掉了,所以左边的迭代器会是一个非法的,会RE。
然后就根本没有问题了。
代码:
#include#include #include const int maxn = 100005;int n, m;struct Nodes{ int l, r; mutable int v; Nodes(int l, int r = -1, int v = 0): l(l), r(r), v(v){} bool operator < (const Nodes &rhs) const { return l < rhs.l; }};std::set chotholly;#define IT std::set ::iteratorIT 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; int 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, int x){ IT itr = split(r + 1), itl = split(l); chotholly.erase(itl, itr); chotholly.insert(Nodes(l, r, x));}void revers(int l, int r){ IT itr = split(r + 1), itl = split(l); for(; itl != itr; ++itl) itl->v ^= 1;}int sum(int l, int r){ int ans = 0; IT itr = split(r + 1), itl = split(l); for(; itl != itr; ++itl) { if(itl->v) ans += (itl->r - itl->l + 1); } return ans;}int coun(int l, int r){ int ans = 0, res = 0; IT itr = split(r + 1), itl = split(l); for(; itl != itr; ++itl) { if(itl->v) { res += (itl->r - itl->l + 1); } else { ans = std::max(ans, res); res = 0; } } ans = std::max(ans, res); return ans;}int main(){ scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) { int val; scanf("%d", &val); chotholly.insert(Nodes(i, i, val)); } //chotholly.insert(Nodes(n, n, 0)); while(m--) { int op, l, r; scanf("%d%d%d", &op, &l, &r); if(op == 0) assign(l, r, false); else if(op == 1) assign(l, r, true); else if(op == 2) revers(l, r); else if(op == 3) printf("%d\n", sum(l, r)); else if(op == 4) printf("%d\n", coun(l, r)); } return 0;}