P2572 [SCOI2010]序列操作
阿新 • • 發佈:2018-10-27
iter -- algorithm res false can != include scanf
暴力數據結構牛逼!!!
這道題給你好多的01串,還有好多的區間統一賦值。
沒錯,你想到了什麽?
珂朵莉樹!
所以你就可以用珂朵莉樹很輕松地水過這道題了!
唯一要註意的是split的順序。必須先split右邊的,再split左邊的。
原因是先split左邊的時候,可能會因為split右邊而導致原叠代器被刪掉了,所以左邊的叠代器會是一個非法的,會RE。
然後就根本沒有問題了。
代碼:
#include<cstdio> #include<set> #include<algorithm> 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<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; 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; }
P2572 [SCOI2010]序列操作