[SCOI2010]序列操作
傻逼線段樹水題……調了好久
結點維護3個標記和幾個資訊……
程式碼實在醜233
Code:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
#define N 1<<17
struct Segment_Tree
{
int l, r, lazy, rest0, rest1, l1max, r1max, max1, l0max, r0max, max0, num, num0, num1, now;
}T[N<<2];
struct doubi
{
int x, l, r;
void clear(){x = l = r = 0;}
};
char c;
int a[N], n, m;
inline void read(int &x)
{
for (c = getchar();c > '9' || c < '0';c = getchar());
for (x = 0;c >= '0' && c <= '9';c = getchar()) x = (x << 3) + (x << 1) + c - '0';
}
inline void ch0(int o)
{
T[o].now = 0;
T[o].max0 = T[o].l0max = T[o].r0max = T[o].num0 = T[o].num;
T[o].max1 = T[o].l1max = T[o].r1max = T[o].num1 = 0;
}
inline void ch1(int o)
{
T[o].now = 1;
T[o].max1 = T[o].l1max = T[o].r1max = T[o].num1 = T[o].num;
T[o].max0 = T[o].l0max = T[o].r0max = T[o].num0 = 0;
}
inline void Updateo(int o)
{
if (T[o<<1].now == T[o<<1|1].now && T[o<<1].now != -1)
{
if (T[o<<1].now)
ch1(o);
else
ch0(o);
}
else
{
T[o].now = -1;
if (T[o<<1].now == 0)
T[o].l0max = T[o<<1].l0max + T[o<<1|1].l0max;
else
T[o].l0max = T[o<<1].l0max;
if (T[o<<1].now == 1)
T[o].l1max = T[o<<1].l1max + T[o<<1|1].l1max;
else
T[o].l1max = T[o<<1].l1max;
if (T[o<<1|1].now == 0)
T[o].r0max = T[o<<1].r0max + T[o<<1|1].r0max;
else
T[o].r0max = T[o<<1|1].r0max;
if (T[o<<1|1].now == 1)
T[o].r1max = T[o<<1].r1max + T[o<<1|1].r1max;
else
T[o].r1max = T[o<<1|1].r1max;
T[o].max0 = max(T[o<<1].r0max + T[o<<1|1].l0max, max(T[o<<1].max0, T[o<<1|1].max0));
T[o].max1 = max(T[o<<1].r1max + T[o<<1|1].l1max, max(T[o<<1].max1, T[o<<1|1].max1));
T[o].num0 = T[o<<1].num0 + T[o<<1|1].num0;
T[o].num1 = T[o<<1].num1 + T[o<<1|1].num1;
}
}
inline void build(int o, int l, int r)
{
T[o].l = l, T[o].r = r;
T[o].num = r - l + 1;
if (l == r)
{
T[o].now = a[l];
if (a[l])
T[o].max1 = T[o].l1max = T[o].r1max = T[o].num1 = 1;
else
T[o].max0 = T[o].l0max = T[o].r0max = T[o].num0 = 1;
return;
}
int mid = (l + r) >> 1;
build(o<<1, l, mid), build(o<<1|1, mid+1, r);
Updateo(o);
}
inline void S(int o)
{
if (T[o].now != -1)
T[o].now ^= 1;
swap(T[o].rest0, T[o].rest1);
swap(T[o].l0max, T[o].l1max);
swap(T[o].r0max, T[o].r1max);
swap(T[o].max0, T[o].max1);
swap(T[o].num0, T[o].num1);
}
inline void Pushdown(int o)
{
if (T[o].lazy)
{
T[o].lazy ^= 1;
if (T[o].l != T[o].r)
{
T[o<<1].lazy ^= 1, T[o<<1|1].lazy ^= 1;
S(o<<1), S(o<<1|1);
}
}
if (T[o].rest0)
{
T[o].rest0 = 0;
if (T[o].l != T[o].r)
{
ch0(o<<1), ch0(o<<1|1);
T[o<<1].rest0 = T[o<<1|1].rest0 = 1;
T[o<<1].rest1 = T[o<<1|1].rest1 = 0;
}
}
if (T[o].rest1)
{
T[o].rest1 = 0;
if (T[o].l != T[o].r)
{
ch1(o<<1), ch1(o<<1|1);
T[o<<1].rest0 = T[o<<1|1].rest0 = 0;
T[o<<1].rest1 = T[o<<1|1].rest1 = 1;
}
}
}
inline doubi Query(int o, int l, int r, int flag)
{
doubi res, resl, resr;
bool L(0), R(0);
res.clear(), resl.clear(), resr.clear();
if (l <= T[o].l && T[o].r <= r)
{
if (flag == 1)
res.x = T[o].num1;
else
{
res.x = T[o].max1;
res.l = T[o].l1max;
res.r = T[o].r1max;
}
return res;
}
Pushdown(o);
int mid = (T[o].l + T[o].r) >> 1;
if (l <= mid)
{
L = 1;
resl = Query(o<<1, l, r, flag);
if (flag == 1)
res.x += resl.x;
}
if (r > mid)
{
R = 1;
resr = Query(o<<1|1, l, r, flag);
if (flag == 1)
res.x += resr.x;
}
if (flag == 1)
return res;
res.x = max(resl.r + resr.l, max(resl.x, resr.x));
if (L && R)
{
if (T[o<<1].now == 1)
res.l = resl.l + resr.l;
else
res.l = resl.l;
if (T[o<<1|1].now == 1)
res.r = resr.r + resl.r;
else
res.r = resr.r;
}
else
{
if (L)
return resl;
if (R)
return resr;
}
return res;
}
inline void Update(int o, int l, int r, int flag)
{
if (l <= T[o].l && T[o].r <= r)
{
if (flag == 2)
S(o), T[o].lazy ^= 1;
else
{
if (T[o].lazy)
Pushdown(o);
if (flag)
T[o].rest0 = 0, T[o].rest1 = 1, ch1(o);
else
T[o].rest1 = 0, T[o].rest0 = 1, ch0(o);
}
return;
}
Pushdown(o);
int mid = (T[o].l + T[o].r) >> 1;
if (l <= mid)
Update(o<<1, l, r, flag);
if (r > mid)
Update(o<<1|1, l, r, flag);
Updateo(o);
}
int main()
{
int i, k, l, r;
read(n), read(m);
for (i = 1;i <= n; ++i)
read(a[i]);
build(1, 1, n);
while (m--)
{
doubi ans;
read(k), read(l), read(r);
l++, r++;
if (k == 0)
Update(1, l, r, 0);
else
if (k == 1)
Update(1, l, r, 1);
else
if (k == 2)
Update(1, l, r, 2);
else
if (k == 3)
ans = Query(1, l, r, 1), printf("%d\n", max(ans.x, max(ans.l, ans.r)));
else
if (k == 4)
ans = Query(1, l, r, 2), printf("%d\n", max(ans.x, max(ans.l, ans.r)));
}
return 0;
}
相關文章
- NC20279 [SCOI2010]序列操作
- bzoj1858: [Scoi2010]序列操作(線段樹)
- C++ 序列操作函式C++函式
- Python 序列通用操作介紹Python
- python序列資料型別之序列資料的基本操作Python資料型別
- NC20566 [SCOI2010]遊戲遊戲
- C++ 序列操作函式最全總結C++函式
- Python 序列與對映的解包操作Python
- Oracle並行操作——從序列到並行Oracle並行
- 使用promis序列化非同步操作非同步
- 有序列表和集合插入操作的耗時差距
- 由序列檢測啟發:資料流滑動視窗操作
- [iOS][OC] 自定義 Promise 處理序列的非同步操作iOSPromise非同步
- rhel5_script自動記錄操作命令歷史序列
- 洛谷 P2569 [SCOI2010] 股票交易 題解
- 資料庫併發如何讓資料操作序列化資料庫
- 卡特蘭數 洛谷P1641 [SCOI2010]生成字串字串
- bzoj1853: [Scoi2010]幸運數字(容斥原理)
- 『無為則無心』Python序列 — 21、Python字典及其常用操作Python
- 『無為則無心』Python序列 — 22、Python集合及其常用操作Python
- 【時間序列分析】01. 時間序列·平穩序列
- 『無為則無心』Python序列 — 17、Python字串操作的常用APIPython字串API
- 【Swift腦洞系列】輕鬆無痛實現非同步操作序列Swift非同步
- 物件序列化(序列化)物件
- Java序列化、反序列化、反序列化漏洞Java
- 各種NLP操作難實現?谷歌開源序列建模框架Lingvo谷歌框架
- 『無為則無心』Python序列 — 18、Python列表概念及常用操作APIPythonAPI
- 序列化與反序列化
- Oracle序列Oracle
- oracle 序列Oracle
- 序列 DP
- Prufer序列
- 裁剪序列
- 為Oracle資料庫表建立自動增長序列及Oracle的常見操作Oracle資料庫
- 序列化與反序列化(GO)Go
- 『無為則無心』Python序列 — 19、Python列表的其他操作(切片和遍歷)Python
- Java的序列化和反序列化Java
- Java的序列化與反序列化Java