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. go1.13errors的用法

    go1.13errors的用法 前言 基本用法 fmt.Errorf Unwrap errors.Is As 扩展 参考 go1.13errors的用法 前言 go 1.13发布了error的一些新的 ...

  2. 内存对齐 align

    /* 地址对齐:指的是存放数据的首地址%N==0,而且整个结构体的大小%M(结构体的有效对齐值)==0 1 数据类型的自身对齐值:char:1 short:2 int,flolat,double:4 ...

  3. 如何改变Xcode字体大小?

    运行Xcode后依次点击左上角Xcode/Preferences/Fonts & Colors里就可以调整,在右边随便点中一个字体就可以调整这个字体的大小和颜色了,按command+a可以将所 ...

  4. [算法]Huffman树(哈夫曼树)

    目录 一.关于Huffman树 二.具体实现 例1:P1090 合并果子 例2:P2168 [NOI2015]荷马史诗 一.关于Huffman树 Huffman树(哈夫曼树)可以解决下述问题: 一颗\ ...

  5. 爬虫实战2_有道翻译sign破解

    目标url 有道翻译 打开网站输入要翻译的内容,一一查找network发现数据返回json格式,红框就是我们的翻译结果 查看headers,发现返回结果的请求是post请求,且携带一大堆form_da ...

  6. 通过dockerfile制作镜像

    Dockerfile是一个用于构建Docker镜像的文本文件,其中包含了创建Docker镜像的全部指令.就是将我们安装环境的每个步骤使用指令的形式存放在一个文件中,最后生成一个需要的环境. Docke ...

  7. vscode 使用记录

    快捷键 Cmd+P 查找最近的文件 Ctrl+cmd + P 打开命令面板 Ctrl+tab文件间切换 Ctrl+` 打开终端 Cmd +b 隐藏侧边栏 VScode对多行编辑有两种模式 第一种模式 ...

  8. python进入adb shell交互模式

    import subprocess #方法一:进入某个环境执行语句(adb shell),注意shell内部命令需要带\n,执行完后一定记得执行exit命令退出,否则会阻塞 obj = subproc ...

  9. fashion_mnist多分类训练,两种模型的保存与加载

    from tensorflow.python.keras.preprocessing.image import load_img,img_to_array from tensorflow.python ...

  10. Java 网络编程 -- 基于TCP 实现聊天室 群聊 私聊

    分析: 聊天室需要多个客户端和一个服务端. 服务端负责转发消息. 客户端可以发送消息.接收消息. 消息分类: 群聊消息:发送除自己外所有人 私聊消息:只发送@的人 系统消息:根据情况分只发送个人和其他 ...