【BZOJ1858】[Scoi2010]序列操作【线段树】

来源:互联网 发布:篮球教学软件大全 编辑:程序博客网 时间:2024/05/17 07:45

【题目链接】

调了一早上,码力++


大概跪了几个地方:

pushdown里rx1手滑打成了rx0。

查询最大子段函数,区间合并忘了上传sum。

mx1合并时候直接写了赋值,忘了和原来的值取max。

/* Pigonometry */#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 100005, maxm = maxn << 2;int n, m, sum[maxm], setv[maxm], xorv[maxm], lx0[maxm], rx0[maxm], mx0[maxm], lx1[maxm], rx1[maxm], mx1[maxm];inline int iread() {int f = 1, x = 0; char ch = getchar();for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';return f * x;}inline void pushup(int p, int l, int mid, int r) {sum[p] = sum[p << 1] + sum[p << 1 | 1];lx0[p] = lx0[p << 1];if(sum[p << 1] == 0) lx0[p] += lx0[p << 1 | 1];rx0[p] = rx0[p << 1 | 1];if(sum[p << 1 | 1] == 0) rx0[p] += rx0[p << 1];mx0[p] = max(max(mx0[p << 1], mx0[p << 1 | 1]), rx0[p << 1] + lx0[p << 1 | 1]);lx1[p] = lx1[p << 1];if(sum[p << 1] == mid - l + 1) lx1[p] += lx1[p << 1 | 1];rx1[p] = rx1[p << 1 | 1];if(sum[p << 1 | 1] == r - mid) rx1[p] += rx1[p << 1];mx1[p] = max(max(mx1[p << 1], mx1[p << 1 | 1]), rx1[p << 1] + lx1[p << 1 | 1]);}inline void pushdown(int p, int l, int mid, int r) {if(~setv[p]) {setv[p << 1] = setv[p << 1 | 1] = setv[p];xorv[p << 1] = xorv[p << 1 | 1] = 0;if(setv[p] == 0) {lx0[p << 1] = rx0[p << 1] = mx0[p << 1] = mid - l + 1;lx0[p << 1 | 1] = rx0[p << 1 | 1] = mx0[p << 1 | 1] = r - mid;lx1[p << 1] = rx1[p << 1] = mx1[p << 1] = 0;lx1[p << 1 | 1] = rx1[p << 1 | 1] = mx1[p << 1 | 1] = 0;sum[p << 1] = sum[p << 1 | 1] = 0;} else {lx0[p << 1] = rx0[p << 1] = mx0[p << 1] = 0;lx0[p << 1 | 1] = rx0[p << 1 | 1] = mx0[p << 1 | 1] = 0;lx1[p << 1] = rx1[p << 1] = mx1[p << 1] = mid - l + 1;lx1[p << 1 | 1] = rx1[p << 1 | 1] = mx1[p << 1 | 1] = r - mid;sum[p << 1] = mid - l + 1; sum[p << 1 | 1] = r - mid;}setv[p] = -1;}if(xorv[p]) {swap(lx0[p << 1], lx1[p << 1]); swap(rx0[p << 1], rx1[p << 1]);swap(mx0[p << 1], mx1[p << 1]); sum[p << 1] = mid - l + 1 - sum[p << 1];swap(lx0[p << 1 | 1], lx1[p << 1 | 1]); swap(rx0[p << 1 | 1], rx1[p << 1 | 1]);swap(mx0[p << 1 | 1], mx1[p << 1 | 1]); sum[p << 1 | 1] = r - mid - sum[p << 1 | 1];if(xorv[p << 1]) xorv[p << 1] = 0;else if(!~setv[p << 1]) xorv[p << 1] = 1;else if(setv[p << 1] == 0) setv[p << 1] = 1;else if(setv[p << 1] == 1) setv[p << 1] = 0;if(xorv[p << 1 | 1]) xorv[p << 1 | 1] = 0;else if(!~setv[p << 1 | 1]) xorv[p << 1 | 1] = 1;else if(setv[p << 1 | 1] == 0) setv[p << 1 | 1] = 1;else if(setv[p << 1 | 1] == 1) setv[p << 1 | 1] = 0;xorv[p] = 0;}}inline void build(int p, int l, int r) {sum[p] = xorv[p] = lx0[p] = rx0[p] = mx0[p] = lx1[p] = rx1[p] = mx1[p] = 0;setv[p] = -1;if(l == r) {int x = iread();if(x == 0) lx0[p] = rx0[p] = mx0[p] = 1;else lx1[p] = rx1[p] = mx1[p] = sum[p] = 1;return;}int mid = l + r >> 1;build(p << 1, l, mid); build(p << 1 | 1, mid + 1, r);pushup(p, l, mid, r);}inline void change(int p, int l, int r, int x, int y, int c) {if(x <= l && r <= y) {if(c == 0) {lx0[p] = rx0[p] = mx0[p] = r - l + 1;lx1[p] = rx1[p] = mx1[p] = sum[p] = 0;} else {lx0[p] = rx0[p] = mx0[p] = 0;lx1[p] = rx1[p] = mx1[p] = sum[p] = r - l + 1;}xorv[p] = 0; setv[p] = c;return;}int mid = l + r >> 1;pushdown(p, l, mid, r);if(x <= mid) change(p << 1, l, mid, x, y, c);if(y > mid) change(p << 1 | 1, mid + 1, r, x, y, c);pushup(p, l, mid, r);}inline void rev(int p, int l, int r, int x, int y) {if(x <= l && r <= y) {swap(lx0[p], lx1[p]); swap(rx0[p], rx1[p]);swap(mx0[p], mx1[p]); sum[p] = r - l + 1 - sum[p];if(xorv[p]) xorv[p] = 0;else if(!~setv[p]) xorv[p] = 1;else if(setv[p] == 0) setv[p] = 1;else if(setv[p] == 1) setv[p] = 0;return;}int mid = l + r >> 1;pushdown(p, l, mid, r);if(x <= mid) rev(p << 1, l, mid, x, y);if(y > mid) rev(p << 1 | 1, mid + 1, r, x, y);pushup(p, l, mid, r);}inline int querysum(int p, int l, int r, int x, int y) {if(x <= l && r <= y) return sum[p];int mid = l + r >> 1, res = 0;pushdown(p, l, mid, r);if(x <= mid) res += querysum(p << 1, l, mid, x, y);if(y > mid) res += querysum(p << 1 | 1, mid + 1, r, x, y);return res;}struct _ans {int lx, rx, mx, sum;};inline _ans querymax(int p, int l, int r, int x, int y) {if(x == l && r == y) return (_ans){lx1[p], rx1[p], mx1[p], sum[p]};int mid = l + r >> 1;pushdown(p, l, mid, r);if(y <= mid) return querymax(p << 1, l, mid, x, y);else if(x > mid) return querymax(p << 1 | 1, mid + 1, r, x, y);else {_ans L = querymax(p << 1, l, mid, x, mid), R = querymax(p << 1 | 1, mid + 1, r, mid + 1, y);_ans ans;ans.sum = L.sum + R.sum;ans.lx = L.lx;if(L.sum == mid - l + 1) ans.lx += R.lx;ans.rx = R.rx;if(R.sum == r - mid) ans.rx += L.rx;ans.mx = max(max(L.mx, R.mx), L.rx + R.lx);return ans;}}int main() {n = iread(); m = iread();build(1, 1, n);while(m--) {int opt = iread(), l = iread(), r = iread(); l++; r++;if(opt == 0 || opt == 1) change(1, 1, n, l, r, opt);else if(opt == 2) rev(1, 1, n, l, r);else if(opt == 3) printf("%d\n", querysum(1, 1, n, l, r));else if(opt == 4) printf("%d\n", querymax(1, 1, n, l, r).mx);}return 0;}

附暴力
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 100005;int n, m, num[maxn];inline int iread() {int f = 1, x = 0; char ch = getchar();for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';return f * x;}inline void output() {for(int i = 1; i <= n; i++) printf("%d ", num[i]);printf("\n");}int main() {freopen("1.in", "r", stdin);freopen("1.ans", "w", stdout);n = iread(); m = iread();for(int i = 1; i <= n; i++) num[i] = iread();while(m--) {int opt = iread(), l = iread(), r = iread(); l++; r++;if(opt == 0) {for(int i = l; i <= r; i++) num[i] = 0;}else if(opt == 1) {for(int i = l; i <= r; i++) num[i] = 1;}else if(opt == 2) {for(int i = l; i <= r; i++) num[i] ^= 1;}else if(opt == 3) {int ans = 0;for(int i = l; i <= r; i++) ans += num[i] == 1;printf("%d\n", ans);}else {int ans = 0, res = 0;for(int i = l; i <= r; i++)if(num[i] == 0) ans = max(ans, res), res = 0;else res++;ans = max(ans, res);printf("%d\n", ans);}//output();}return 0;}

和mk
#include <cstdio>#include <cstdlib>#include <ctime>#include <algorithm>using namespace std;typedef long long LL;inline int rd(int x) {return (LL)rand() * rand() % x + 1;}int main() {freopen("1.in", "w", stdout);srand(time(0));int n = 1000, m = 1000;printf("%d %d\n", n, m);for(int i = 1; i <= n; i++) printf("%d ", rd(2) - 1);printf("\n");for(int i = 1; i <= m; i++) {int opt = rd(5) - 1, l = rd(n), r = rd(n);//for(; opt == 3; opt = rd(5) - 1);if(l > r) swap(l, r);printf("%d %d %d\n", opt, l - 1, r - 1);}return 0;}



0 0
原创粉丝点击