bzoj 1858 序列操作(线段树)
来源:互联网 发布:abp框架源码 编辑:程序博客网 时间:2024/06/05 14:48
题外话
本来想练练线段树的,然后发现这题及其蛋疼,要打一坨标记,这是我写过的最长的线段树了= =
然后我很SB的把R打成了r调了一个下午真是蛋疼QvQ
Description:
Solution
没有操作
我们需要从左端点开始连续
区间内
然后我们就可以合并辣!
具体合并情况想想清楚就好了
Code
#include <bits/stdc++.h>//好题using namespace std;#define ls (rt << 1)#define rs (rt << 1 | 1)const int N = 100005;struct Node { int lc[2], rc[2], mx[2], cnt[2], len; }p[N << 2];int a[N], flag[N << 2];void pushup(int rt) { p[rt].cnt[0] = p[ls].cnt[0] + p[rs].cnt[0]; p[rt].cnt[1] = p[ls].cnt[1] + p[rs].cnt[1]; p[rt].lc[0] = p[ls].lc[0] + (p[ls].lc[0] == p[ls].len ? p[rs].lc[0] : 0); p[rt].lc[1] = p[ls].lc[1] + (p[ls].lc[1] == p[ls].len ? p[rs].lc[1] : 0); p[rt].rc[0] = p[rs].rc[0] + (p[rs].rc[0] == p[rs].len ? p[ls].rc[0] : 0); p[rt].rc[1] = p[rs].rc[1] + (p[rs].rc[1] == p[rs].len ? p[ls].rc[1] : 0); p[rt].mx[0] = max(p[ls].mx[0], max(p[rs].mx[0], p[ls].rc[0] + p[rs].lc[0])); p[rt].mx[1] = max(p[ls].mx[1], max(p[rs].mx[1], p[ls].rc[1] + p[rs].lc[1]));}void build(int rt, int l, int r) { flag[rt] = -1; p[rt].len = r - l + 1; if (l == r) { p[rt].lc[a[l]] = p[rt].rc[a[l]] = p[rt].mx[a[l]] = p[rt].cnt[a[l]] = 1; return; } int mid = l + r >> 1; build(ls, l, mid); build(rs, mid + 1, r); pushup(rt);}void pushdown(int rt, int l, int r) { if (~flag[rt]) { int x = flag[rt]; if (x == 2) { swap(p[ls].lc[0], p[ls].lc[1]), swap(p[rs].lc[0], p[rs].lc[1]); swap(p[ls].rc[0], p[ls].rc[1]), swap(p[rs].rc[0], p[rs].rc[1]); swap(p[ls].cnt[0], p[ls].cnt[1]), swap(p[rs].cnt[0], p[rs].cnt[1]); swap(p[ls].mx[0], p[ls].mx[1]), swap(p[rs].mx[0], p[rs].mx[1]); flag[ls] = 1 - flag[ls], flag[rs] = 1 - flag[rs]; } else { p[ls].lc[x] = p[ls].rc[x] = p[ls].cnt[x] = p[ls].mx[x] = p[ls].len; p[ls].lc[1 - x] = p[ls].rc[1 - x] = p[ls].cnt[1 - x] = p[ls].mx[1 - x] = 0; p[rs].lc[x] = p[rs].rc[x] = p[rs].cnt[x] = p[rs].mx[x] = p[rs].len; p[rs].lc[1 - x] = p[rs].rc[1 - x] = p[rs].cnt[1 - x] = p[rs].mx[1 - x] = 0; flag[ls] = flag[rs] = flag[rt]; } flag[rt] = -1; }}void change(int rt, int l, int r, int L, int R, int x) { if (L <= l && R >= r) { p[rt].lc[x] = p[rt].rc[x] = p[rt].cnt[x] = p[rt].mx[x] = p[rt].len; p[rt].lc[1 - x] = p[rt].rc[1 - x] = p[rt].cnt[1 - x] = p[rt].mx[1 - x] = 0; flag[rt] = x; return; } pushdown(rt, l, r); int mid = l + r >> 1; if (mid < L) change(rs, mid + 1, r, L, R, x); else if (mid >= R) change(ls, l, mid, L, R, x); else { change(ls, l, mid, L, mid, x); change(rs, mid + 1, r, mid + 1, R, x); } pushup(rt);}void reverse(int rt, int l, int r, int L, int R) { if (L <= l && R >= r) { swap(p[rt].lc[0], p[rt].lc[1]), swap(p[rt].rc[0], p[rt].rc[1]); swap(p[rt].cnt[0], p[rt].cnt[1]), swap(p[rt].mx[0], p[rt].mx[1]); flag[rt] = 1 - flag[rt]; return; } pushdown(rt, l, r); int mid = l + r >> 1; if (mid < L) reverse(rs, mid + 1, r, L, R); else if (mid >= R) reverse(ls, l, mid, L, R); else { reverse(ls, l, mid, L, mid); reverse(rs, mid + 1, r, mid + 1, R); } pushup(rt); }int ask(int rt, int l, int r, int L, int R) { if (L <= l && R >= r) return p[rt].cnt[1]; pushdown(rt, l, r); int mid = l + r >> 1; if (mid < L) return ask(rs, mid + 1, r, L, R); else if (mid >= R) return ask(ls, l, mid, L, R); else return ask(ls, l, mid, L, mid) + ask(rs, mid + 1, r, mid + 1, R);}Node ask2(int rt, int l, int r, int L, int R) { if (L <= l && R >= r) return p[rt]; pushdown(rt, l, r); int mid = l + r >> 1; if (mid < L) return ask2(rs, mid + 1, r, L, R); else if (mid >= R) return ask2(ls, l, mid, L, R); else { Node t1 = ask2(ls, l, mid, L, mid), t2 = ask2(rs, mid + 1, r, mid + 1, R); Node t3; t3.lc[1] = t1.lc[1] + (t1.lc[1] == t1.len ? t2.lc[1] : 0); t3.rc[1] = t2.rc[1] + (t2.rc[1] == t2.len ? t1.rc[1] : 0); t3.len = t1.len + t2.len; t3.mx[1] = max(t1.mx[1], max(t2.mx[1], t1.rc[1] + t2.lc[1])); return t3; }}int main() { int n, q; scanf("%d%d",&n, &q); for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); build(1, 1, n); while (q--) { int x, l, r; scanf("%d%d%d", &x, &l, &r); ++l, ++r; switch(x) { case 0: change(1, 1, n, l, r, 0);break; case 1: change(1, 1, n, l, r, 1);break; case 2: reverse(1, 1, n, l, r);break; case 3: printf("%d\n", ask(1, 1, n, l, r));break; case 4: { Node t = ask2(1, 1, n, l, r); printf("%d\n", t.mx[1]); } } } return 0;}
0 0
- BZOJ 1858 SCOI2010 序列操作 线段树
- bzoj 1858 序列操作(线段树)
- bzoj 1858 序列操作 线段树
- BZOJ 1858 [Scoi2010]序列操作 线段树
- 【bzoj 1858】 [Scoi2010]序列操作 线段树
- bzoj 1858: [Scoi2010]序列操作 线段树
- BZOJ 1858 [Scoi2010]序列操作 线段树
- BZOJ 1858 [Scoi2010]序列操作 线段树
- BZOJ 1858 序列操作 [线段树]
- BZOJ 1858: [Scoi2010]序列操作 线段树
- BZOJ 1858: [Scoi2010]序列操作 线段树
- bzoj 1858: [Scoi2010]序列操作(线段树)
- BZOJ 1858: [Scoi2010]序列操作 线段树区间修改查询
- [BZOJ 1858][Scoi2010]序列操作(线段树)
- 【BZOJ 1858】【SCOI 2010】序列操作【区间线段树】
- bzoj 2962 序列操作(线段树)
- BZOJ 2962 序列操作 线段树
- BZOJ 2962 序列操作 线段树
- hadoop/spark调优以及遇到的问题
- 选择排序
- 如何获得设备环境句柄(HDC)--Win32 SDK
- 国内各大城市的IT行业特色
- Android开发--大神博客汇总
- bzoj 1858 序列操作(线段树)
- uvalive3266(田忌赛马)
- 修理牛棚(贪心)
- NOJ 1972 炒股票的女巫璐璐 && NOJ 1974 BRN (浅谈两点法)
- crtmpserver启动和vlc播放rtmp流程
- xetex安装及中文化字体配置
- Java—简单的缓存系统
- kali+python安装rsa模块
- leecode:Maximum depth of binary tree: 菜鸟解法