F - Sequence operation


题解:
这个题目不是一个特别难的题目,但是呢,写了好久,首先线段树难敲,其次就是bug难找,最后这个代码都被我改的乱七八糟的了,
这个有两个地方要注意一下,一个是取反的lazy标志,每次取反都是对1取异或,还有一个也是这个取反的lazy标志,
这个标志再第一种操作之后要进行消除。
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <iostream>
#include <stack>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e6 + ;
struct node
{
int sum;
int max_sub, max_zero;
int l, r, len;
int lazy1, lazy2;
int max_prezero, max_lastzero;
int max_preone, max_lastone;
}tree[maxn * ];
int a[maxn]; void push_up(int id)
{
tree[id].sum = tree[id << ].sum + tree[id << | ].sum; tree[id].max_preone = tree[id << ].max_preone;
if (tree[id].max_preone == tree[id << ].len) tree[id].max_preone += tree[id << | ].max_preone;
tree[id].max_lastone = tree[id << | ].max_lastone;
if (tree[id].max_lastone == tree[id << | ].len) tree[id].max_lastone += tree[id << ].max_lastone;
tree[id].max_sub = max(tree[id << ].max_lastone + tree[id << | ].max_preone, max(tree[id << ].max_sub, tree[id << | ].max_sub)); tree[id].max_prezero = tree[id << ].max_prezero;
if (tree[id].max_prezero == tree[id << ].len) tree[id].max_prezero += tree[id << | ].max_prezero;
tree[id].max_lastzero = tree[id << | ].max_lastzero;
if (tree[id].max_lastzero == tree[id << | ].len) tree[id].max_lastzero += tree[id << ].max_lastzero;
tree[id].max_zero = max(tree[id << ].max_lastzero + tree[id << | ].max_prezero, max(tree[id << ].max_zero, tree[id << | ].max_zero)); return;
} void chang1(int id, int val)
{
if (val)
{
tree[id].sum = tree[id].len;
tree[id].max_preone = tree[id].max_lastone = tree[id].max_sub = tree[id].len;
tree[id].max_zero = tree[id].max_prezero = tree[id].max_lastzero = ;
}
else
{
tree[id].sum = ;
tree[id].max_preone = tree[id].max_lastone = tree[id].max_sub = ;
tree[id].max_zero = tree[id].max_prezero = tree[id].max_lastzero = tree[id].len;
}
} void chang2(int id)
{
swap(tree[id].max_sub, tree[id].max_zero);
swap(tree[id].max_prezero, tree[id].max_preone);
swap(tree[id].max_lastone, tree[id].max_lastzero);
tree[id].sum = tree[id].len - tree[id].sum;
} void push_down(int id)
{
if (tree[id].lazy1)
{
chang1(id << , tree[id].lazy1 - );
chang1(id << | , tree[id].lazy1 - );
tree[id << ].lazy1 = tree[id << | ].lazy1 = tree[id].lazy1;
tree[id << ].lazy2 =tree[id << | ].lazy2 = ;
tree[id].lazy1 = ;
}
if (tree[id].lazy2)
{
chang2(id << );
chang2(id << | ); tree[id << ].lazy2 ^= ;
tree[id << | ].lazy2 ^= ;
tree[id].lazy2 = ;
}
} void build(int id, int l, int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].lazy1 = ;
tree[id].lazy2 = ;
tree[id].len = r - l + ;
if (l == r)
{
if (a[l]) chang1(id, );
else chang1(id, );
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
push_up(id);
} void update_change(int id, int l, int r, int z)
{
if (l <= tree[id].l&&r >= tree[id].r)
{
chang1(id, z);
tree[id].lazy1 = z + ;
tree[id].lazy2 = ;
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) >> ;
if (l <= mid) update_change(id << , l, r, z);
if (r > mid) update_change(id << | , l, r, z);
push_up(id);
} void update_trans(int id, int l, int r)
{
if (l <= tree[id].l&&r >= tree[id].r)
{
tree[id].lazy2 ^= ;
chang2(id);
return;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) >> ;
if (l <= mid) update_trans(id << , l, r);
if (r > mid) update_trans(id << | , l, r);
push_up(id);
} int query_sum(int id, int l, int r)
{
if (l <= tree[id].l&&r >= tree[id].r)
{
return tree[id].sum;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) >> , ans = ;
if (l <= mid) ans += query_sum(id << , l, r);
if (r > mid) ans += query_sum(id << | , l, r);
return ans;
} int query(int id, int l, int r)
{
int ans = ;
if (l <= tree[id].l&&r >= tree[id].r)
{
return tree[id].max_sub;
}
push_down(id);
int mid = (tree[id].l + tree[id].r) >> ;
if (l <= mid) ans = max(ans, query(id << , l, r));
if (r > mid) ans = max(ans, query(id << | , l, r));
ans = max(ans, min(mid - l + , tree[id << ].max_lastone) + min(r - mid, tree[id << | ].max_preone));
return ans;
} int main()
{
int t;
cin >> t;
while (t--)
{
int n, m;
cin >> n >> m;
for (int i = ; i <= n; i++) scanf("%d", &a[i]);
build(, , n);
while (m--)
{
int c, x, y;
scanf("%d%d%d", &c, &x, &y);
if (c == ) update_change(, x + , y + , );
if (c == ) update_change(, x + , y + , );
if (c == ) update_trans(, x + , y + );
if (c == )
{
int ans = query_sum(, x + , y + );
printf("%d\n", ans);
}
if (c == )
{
int ans = query(, x + , y + );
printf("%d\n", ans);
}
}
}
return ;
}
												

线段树 区间合并 F - Sequence operation的更多相关文章

  1. HYSBZ 1858 线段树 区间合并

    //Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...

  2. poj3667 线段树 区间合并

    //Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...

  3. hdu3911 线段树 区间合并

    //Accepted 3911 750MS 9872K //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...

  4. SPOJ GSS1_Can you answer these queries I(线段树区间合并)

    SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...

  5. 树链剖分——线段树区间合并bzoj染色

    线段树区间合并就挺麻烦了,再套个树链就更加鬼畜,不过除了代码量大就没什么其他的了.. 一些细节:线段树每个结点用结构体保存,pushup等合并函数改成返回一个结构体,这样好写一些 struct Seg ...

  6. poj3667 Hotel (线段树 区间合并)

    poj3667 HotelTime Limit: 3000MS Memory Limit: 65536KTotal Submissions: 18925 Accepted: 8242Descripti ...

  7. hdu-3308 LCIS (线段树区间合并)

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  8. Tunnel Warfare(HDU1540+线段树+区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540 题目: 题意:总共有n个村庄,有q次操作,每次操作分为摧毁一座村庄,修复一座村庄,和查询与询问的 ...

  9. hdu 3308(线段树区间合并)

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

随机推荐

  1. Eureka源码分析

    源码流程图 先上图,不太清晰,抱歉 一.Eureka Server源码分析 从@EnableEurekaServer注解为入口,它是一个标记注解,点进去看 注解内容如下 /** * 激活Eureka服 ...

  2. 2016NOIP普及组T2回文日期

    回文日期 分类:枚举,函数 [题目描述] 日常生活中,通过年.月.日这三个要素可以表示出一个唯一确定的日期. 牛牛习惯用8位数字表示一个日期,其中,前4位代表年份,接下来2位代表月份,最后2位代表日期 ...

  3. [复现]GXY2019

    前言 当时GXY的时候在复习中,临时抱拂脚,没时间打比赛.就写了一题./(ㄒoㄒ)/~~ babysqli 当时做了写了笔记. 过滤了or,()其中or可以用大小写绕过,可以用order by盲注 第 ...

  4. BUUOJ [CISCN2019 华北赛区 Day2 Web1]Hack World

    补一下这道题,顺便发篇博客 不知道今年国赛是什么时候,菜鸡还是来刷刷题好了 0X01 考点 SQL注入.盲注.数字型 0X02自己尝试 尝试输入1 赵师傅需要女朋友吗???随便都能有好吧 输入2 ?? ...

  5. CVE 2019-0708 漏洞复现+

    PART 1 参考链接:https://blog.csdn.net/qq_42184699/article/details/90754333 漏洞介绍: 当未经身份验证的攻击者使用 RDP 连接到目标 ...

  6. ASP.NET Core 与 ASPOSE.Words for .NET

    Aspose.Total是Aspose公司旗下的最全的一套office文档管理方案,它提供的原生API可以对Word.Excel.PDF.Powerpoint.Outlook.CAD.图片.3D.ZI ...

  7. 在php中如何实现cookie即时生效,不用刷新就可以使用

    参考:https://www.jianshu.com/p/0468ef5dbf4d 今天在用php设置cookie的时候,发现cookie如果只是赋值一次的话,要手动刷新一下浏览器才能把数据及时更新, ...

  8. awk,seq,xarg实例使用

    基于https://www.cnblogs.com/wangyuebo/p/5836933.html的详细补充讲解 [root@localhost awk]# seq 10|xargs -n 2 &g ...

  9. HTML入门——互动式推送初尝试

    0.背景 疫情原因,导致许多大众喜闻乐见的体育活动停摆,但博主和队友们运营的体育社团公众号不能停摆.为了利用当下线上活动频率高的契机增加关注量,加之微信推送的互动性已成为趋势,博主打算和队友们尝试实现 ...

  10. vue2.x学习笔记(二十六)

    接着前面的内容:https://www.cnblogs.com/yanggb/p/12682137.html. 单文件组件 介绍 在很多的vue项目中,我们都是使用[Vue.component]来定义 ...