博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[SCOI2010]序列操作 BZOJ1858 线段树
阅读量:7089 次
发布时间:2019-06-28

本文共 6424 字,大约阅读时间需要 21 分钟。

题目描述

lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作:

0 a b 把[a, b]区间内的所有数全变成0

1 a b 把[a, b]区间内的所有数全变成1

2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0

3 a b 询问[a, b]区间内总共有多少个1

4 a b 询问[a, b]区间内最多有多少个连续的1

对于每一种询问操作,lxhgww都需要给出回答,聪明的程序员们,你们能帮助他吗?

输入输出格式

输入格式:

输入数据第一行包括2个数,n和m,分别表示序列的长度和操作数目

第二行包括n个数,表示序列的初始状态

接下来m行,每行3个数,op, a, b,(0<=op<=4,0<=a<=b<n)表示对于区间[a, b]执行标号为op的操作

输出格式:

对于每一个询问操作,输出一行,包括1个数,表示其对应的答案

输入输出样例

输入样例#1:
10 10   0 0 0 1 1 0 1 0 1 1   1 0 2   3 0 5   2 2 2   4 0 4   0 3 6   2 3 7   4 2 8   1 0 5   0 5 6   3 3 9
输出样例#1:
5265

说明

对于30%的数据,1<=n, m<=1000

对于100%的数据,1<=n, m<=100000

 

很刺激的线段树题目;

注意赋值的操作的优先级>翻转的操作;

还有很多细节要注意;

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
//#pragma GCC optimize(2)using namespace std;#define maxn 300005#define inf 0x3f3f3f3f#define INF 9999999999#define rdint(x) scanf("%d",&x)#define rdllt(x) scanf("%lld",&x)#define rdult(x) scanf("%lu",&x)#define rdlf(x) scanf("%lf",&x)#define rdstr(x) scanf("%s",x)typedef long long ll;typedef unsigned long long ull;typedef unsigned int U;#define ms(x) memset((x),0,sizeof(x))const long long int mod = 1e9 + 7;#define Mod 1000000000#define sq(x) (x)*(x)#define eps 1e-3typedef pair
pii;#define pi acos(-1.0)const int N = 1005;#define REP(i,n) for(int i=0;i<(n);i++)typedef pair
pii;inline ll rd() { ll x = 0; char c = getchar(); bool f = false; while (!isdigit(c)) { if (c == '-') f = true; c = getchar(); } while (isdigit(c)) { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return f ? -x : x;}ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a%b);}ll sqr(ll x) { return x * x; }/*ll ans;ll exgcd(ll a, ll b, ll &x, ll &y) { if (!b) { x = 1; y = 0; return a; } ans = exgcd(b, a%b, x, y); ll t = x; x = y; y = t - a / b * y; return ans;}*/ll qpow(ll a, ll b, ll c) { ll ans = 1; a = a % c; while (b) { if (b % 2)ans = ans * a%c; b /= 2; a = a * a%c; } return ans;}struct node { int sum; int Lw, Lb;// Lb:区间连续0的最大长度,Lw:连续1的最大长度 int llw, rlw;//llb:区间左端点连续0的最大长度,llw:区间左端点连续1的最大长度; int llb, rlb;// rlb:区间右端点连续0的最大长度;rlw:区间右端点连续1的最大长度 int lazy, rev;// lazy:是否全部变为1/0;rev:翻转标记}tr[maxn<<2];int n, m;#define lson (rt<<1)#define rson (rt<<1|1)#define mid ((l+r)>>1)void pushup(int l, int r, int rt) { tr[rt].sum = tr[lson].sum + tr[rson].sum; tr[rt].Lb = max(tr[lson].Lb, tr[rson].Lb); tr[rt].Lw = max(tr[lson].Lw, tr[rson].Lw); tr[rt].llb = tr[lson].llb; tr[rt].llw = tr[lson].llw; if (tr[lson].llw == mid - l + 1)tr[rt].llw += tr[rson].llw; if (tr[lson].llb == mid - l + 1)tr[rt].llb += tr[rson].llb; tr[rt].rlb = tr[rson].rlb; tr[rt].rlw = tr[rson].rlw; if (tr[rson].rlb == r - mid)tr[rt].rlb += tr[lson].rlb; if (tr[rson].rlw == r - mid)tr[rt].rlw += tr[lson].rlw; tr[rt].Lw = max(tr[rt].Lw, tr[lson].rlw + tr[rson].llw); tr[rt].Lb = max(tr[rt].Lb, tr[lson].rlb + tr[rson].llb);}void down(int l, int r, int rt) { int lazy = tr[rt].lazy, rev = tr[rt].rev; int L1 = mid - l + 1, L2 = r - mid; tr[rt].lazy = -1; if (lazy == 0) { tr[lson] = node { 0, 0, L1, 0, 0, L1, L1, 0, 0 }; tr[rson] = node{ 0,0,L2,0,0,L2,L2,0,0 }; } else if (lazy == 1) { tr[lson] = node{ L1,L1,0,L1,L1,0,0,1,0 }; tr[rson] = node{ L2,L2,0,L2,L2,0,0,1,0 }; } if (rev) { tr[rt].rev = 0; int sum = tr[lson].sum; int Lw = tr[lson].Lw, Lb = tr[lson].Lb; int llw = tr[lson].llw, llb = tr[lson].llb; int rlw = tr[lson].rlw, rlb = tr[lson].rlb; tr[lson].sum = L1 - sum; tr[lson].Lw = Lb; tr[lson].Lb = Lw; tr[lson].llw = llb; tr[lson].rlw = rlb; tr[lson].llb = llw; tr[lson].rlb = rlw; tr[lson].rev ^= 1; sum = tr[rson].sum; Lw = tr[rson].Lw; Lb = tr[rson].Lb; llw = tr[rson].llw; llb = tr[rson].llb; rlw = tr[rson].rlw; rlb = tr[rson].rlb; tr[rson].sum = L2 - sum; tr[rson].Lw = Lb; tr[rson].Lb = Lw; tr[rson].llw = llb; tr[rson].rlw = rlb; tr[rson].llb = llw; tr[rson].rlb = rlw; tr[rson].rev ^= 1; }}void build(int l, int r, int rt) { tr[rt].lazy = -1; if (l == r) { int x; rdint(x); tr[rt] = node{ x,x,(x ^ 1),x,x,(x ^ 1),(x ^ 1),-1,0 }; return; } build(l, mid, lson); build(mid + 1, r, rson); pushup(l, r, rt);}void upd1(int l, int r, int rt, int L, int R) { if (L <= l && r <= R) { int LL = r - l + 1; tr[rt] = node{ 0,0,LL,0,0,LL,LL,0,0 }; return; } if (l > R || r < L)return; down(l, r, rt); upd1(l, mid, lson, L, R); upd1(mid + 1, r, rson, L, R); pushup(l, r, rt);}void upd2(int l, int r, int rt, int L, int R) { if (L <= l && r <= R) { int LL = r - l + 1; tr[rt] = node{ LL,LL,0,LL,LL,0,0,1,0 }; return; } if (l > R || r < L)return; down(l, r, rt); upd2(l, mid, lson, L, R); upd2(mid + 1, r, rson, L, R); pushup(l, r, rt);}void upd3(int l, int r, int rt, int L, int R) { if (L <= l && r <= R) { int LL = r - l + 1, sum = tr[rt].sum, Lw = tr[rt].Lw, Lb = tr[rt].Lb; int llw = tr[rt].llw, llb = tr[rt].llb; int rlw = tr[rt].rlw, rlb = tr[rt].rlb; tr[rt] = node{ LL - sum,Lb,Lw,llb,rlb,llw,rlw,tr[rt].lazy,(tr[rt].rev ^ 1) }; return; } if (l > R || r < L)return; down(l, r, rt); upd3(l, mid, lson, L, R); upd3(mid + 1, r, rson, L, R); pushup(l, r, rt);}int query1(int l, int r, int rt, int L, int R) { if (L <= l && r <= R)return tr[rt].sum; if (l > R || r < L)return 0; down(l, r, rt); return query1(l, mid, lson, L, R) + query1(mid + 1, r, rson, L, R);}node query2(int l, int r, int rt, int L, int R) { if (L <= l && r <= R)return tr[rt]; if (l > R || r < L)return node{ 0 }; down(l, r, rt); node LL = query2(l, mid, lson, L, R), RR = query2(mid + 1, r, rson, L, R), ans; ans.sum = LL.sum + RR.sum; ans.Lw = max(LL.Lw, RR.Lw); ans.Lb = max(LL.Lb, RR.Lb); ans.llw = LL.llw, ans.rlw = RR.rlw; ans.llb = LL.llb, ans.rlb = RR.rlb; if (LL.llb == mid - l + 1)ans.llb += RR.llb; if (LL.llw == mid - l + 1)ans.llw += RR.llw; if (RR.rlb == r - mid)ans.rlb += LL.rlb; if (RR.rlw == r - mid)ans.rlw += LL.rlw; ans.Lw = max(ans.Lw, LL.rlw + RR.llw); ans.Lb = max(ans.Lb, LL.rlb + RR.llb); return ans;}int main(){ //ios::sync_with_stdio(0); rdint(n); rdint(m); build(1, n, 1); while (m--) { int op, a, b; rdint(op); rdint(a); rdint(b); a++; b++; if (op == 0)upd1(1, n, 1, a, b); if (op == 1)upd2(1, n, 1, a, b); if (op == 2)upd3(1, n, 1, a, b); if (op == 3)cout << query1(1, n, 1, a, b) << endl; if (op == 4)cout << query2(1, n, 1, a, b).Lw << endl; } return 0;}

 

转载于:https://www.cnblogs.com/zxyqzy/p/10118027.html

你可能感兴趣的文章
Linux下动态加载SO文件
查看>>
Mysql创建、删除用户
查看>>
我的友情链接
查看>>
MySQL-MySQL常用命令
查看>>
Linux iptraf 网络监控
查看>>
Swift::8::枚举
查看>>
ZABBIX web端 显示 server 运行状态 不
查看>>
Aspose.Words使用教程之在文档中找到并替换文本
查看>>
ORACLE官方文档如何学习
查看>>
google guava包集合类HashMultiset的基本用法
查看>>
linux 进程和线程
查看>>
网工考试!
查看>>
Spring Boot 项目脚本(启动、停止、重启、状态)
查看>>
专访路彦雄:理解语言其实还是很难的
查看>>
Windows 2003服务器群集(负载均衡)简介
查看>>
日程日历示例
查看>>
linux下解决对外udp***
查看>>
fluuter 浮动 和 触摸
查看>>
IPTABLES实战
查看>>
11月下旬全球域名解析商TOP15:万网0.95%居第12
查看>>