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. jpa是什么,和hibernate 有什么关系

    JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中.JPA 的目标之一是制定一个可以由很多供应商实现的API,并且开发人员可以编码来实现该API,而不 ...

  2. AJ学IOS(15)UI之曾经大热的打砖块小游戏

    AJ分享,必须精品 先看效果图 代码 // ViewController.m // 打砖块 // // Created by liufan on 13-8-17. // Copyright (c) 2 ...

  3. 试验使用t检验

    官方解释 Excel中使用T.TEST函数 T.TEST(array1,array2,tails,type) Array1      必需.第一个数据集. Array2      必需.第二个数据集. ...

  4. [译]谈谈SpringBoot 事件机制

    要"监听"事件,我们总是可以将"监听器"作为事件源中的另一个方法写入事件,但这将使事件源与监听器的逻辑紧密耦合. 对于实际事件,我们比直接方法调用更灵活.我们可 ...

  5. 「日常开发」记一次因使用Date引起的线上BUG处理

    生活中,我们需要掌控自己的时间,减少加班,提高效率:日常开发中,我们需要操作时间API,保证效率.安全.稳定.现在都2020年了,了解如何在JDK8及以后的版本中更好地操控时间就很有必要,尤其是一次线 ...

  6. JMeter在Mac下的安装

    其实不论操作系统是Windows.Unix(如Mac OS).Linux(如Ubuntu)等,JMeter所需要的基础环境配置都是类似的,本文介绍JMeter for MAC的安装与环境配置. JMe ...

  7. 如何在非 sudo 用户下运行 docker 命令?

    当我们在一台 Linux 系统中安装了 Docker 后, 有时候会遇到下面这样的错误, 我们在运行 docker 的命令时必须加上 sudo, 例如: sudo docker ps, 但是我们其实更 ...

  8. 加不加 synchronized 有什么区别?

    今天一起来认识认识 synchronized 这个一面试就会被提到的关键字.这一篇不会讲太多理论,主要先熟悉熟悉一下最简单的用法.只讨论一个问题:方法没用 synchronized 和用了 synch ...

  9. Java 创建 Excel 数据透视表

    Excel 数据透视表具有强大的数据处理功能,能够使表格中的数据更加直观化.使用Excel 数据透视表,能方便用户快速的排序. 筛选各种数据,同时也能满足用户对不同数据汇总的需求.本文将介绍如何在Ja ...

  10. 只会Vue怎么开发小程序?vue和微信小程序的到底有哪些区别?

    写了vue项目和小程序,发现二者有许多相同之处,在此想总结一下二者的共同点和区别. 一.生命周期 先贴两张生命周期图对比下: vue生命周期 小程序生命周期 相比之下,小程序的钩子函数要简单得多. v ...