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. MyBatis通用 Mapper4使用小结

    官网地址: http://www.mybatis.tk/ https://gitee.com/free 1.使用springboot,添加依赖: 使用tk的mybatis后不需要引用官方原生的myba ...

  2. SpringBoot项目中容易出现的问题

    SpringBoot项目的配置文件 另外启动文件的位置一定要在其它类的顶层,SpringBoot所在的main函数的同级包或子包在生效 开始做这个的时候最容易把配置文件搞错,造成sql查询异常

  3. SwiftUI - 一步一步教你使用UIViewRepresentable封装网络加载视图(UIActivityIndicatorView)

    概述 网络加载视图,在一个联网的APP上可以讲得上是必须要的组件,在SwiftUI中它并没有提供如 UIKit 中的UIActivityIndicatorView直接提供给我们调用,但是我们可以通过 ...

  4. 数据结构之循环队列Demo

    循环队列 比较简单,循环队列主要是判断队满.队空.有效元素个数 画图说明: 假设:队的长度为5(0-4) 但是实际maxsize为6,需要一个预留空间(不存储元素)做计算 继续添加3个元素后: 出队一 ...

  5. C. Standard Free2play --div

    https://codeforces.com/contest/1238/problem/C 题意:下台阶的时候只有一种方式,拉动当前台阶x的 level,然后当前的台阶关闭,调到下边的台阶x-1,如果 ...

  6. Unity 游戏框架搭建 2019 (二十九) 方法所在类命名问题诞生的原因

    我们在整理阶段解决了一些意外的问题.但是这些问题仅仅只是被解决而已,我们并没有去思考过这些问题是为什么产生的?以及在以后我们如何去避免这些问题的产生? 方法所在类的命名问题,最后我们通过方法分类解决了 ...

  7. JAVA的synchronized写法

    使用关键字synchronized的写法比较多,常用的有如下几种,代码如下: public class MyService { synchronized public static void test ...

  8. eclipse git 文件状态 及git分支的创建与合并与删除

    eclipse里面Git文件状态及图标展示   EGit会出现如下图标,其对应状态及意义如下:      1)忽略[ ignored ]:仓库认为该文件不存在(如bin目录,不需要关注).通过右键Te ...

  9. phpstudy之访问loaclhost显示目录

    phpstudy版本:phpstudy2018 具体操作: 当前版本的默认设置访问网站根目录是不会显示目录的,需要我们设置,其实也很简单,只需两步就可以搞定 1.找到phpstudy目录下的www文件 ...

  10. Java中基础类基础方法(学生类)(手机类)

    学生类: //这是我的学生类class Student { //定义变量 //姓名 String name; //null //年龄 int age; //0 //地址 String address; ...