hdu 3397 线段树+区间合并+懒惰标记 好题

lattice Diamond Programmer程序下载 Lattice Diamond Programmer(支持Lattice FPGA与CPLD程序下载) 阅读详情

Sequence operation

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4603    Accepted Submission(s): 1338


Problem Description
lxhgww got a sequence contains n characters which are all '0's or '1's.
We have five operations here:
Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]
 

Input
T(T<=10) in the first line is the case number.
Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
The next line contains n characters, '0' or '1' separated by spaces.
Then m lines are the operations:
op a b: 0 <= op <= 4 , 0 <= a <= b < n.
 

Output
For each output operation , output the result.
 

Sample Input
  
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
 

Sample Output
  
5 2 6 5
 

Author
lxhgww&&shǎ崽
 

Source
 

Recommend
lcy
 
很好的一道题,考你有没有理解懒惰标记的本质~~
ps:这是我写的最长的代码了吧~~~
#include <iostream>
#include <cstring>
#include <cstdio>
#define lson pos<<1
#define rson pos<<1|1
using namespace std;
const int MAXN=100005;
int num[MAXN];
struct node
{
    int l,r;
    int msum1,msum0;   //连续最长1和0
    int lsum1,lsum0;   //左起最长
    int rsum1,rsum0;   //右起最长
    int lazy;          //标记
    int sum;           //最长1
    int mid()
    {
        return (l+r)>>1;
    }
};
node tree[MAXN*4];
inline void pushup(int pos)
{
    tree[pos].msum0=max(tree[lson].msum0,tree[rson].msum0);
    tree[pos].msum1=max(tree[lson].msum1,tree[rson].msum1);
    tree[pos].lsum0=tree[lson].lsum0;
    tree[pos].lsum1=tree[lson].lsum1;
    tree[pos].rsum0=tree[rson].rsum0;
    tree[pos].rsum1=tree[rson].rsum1;
    tree[pos].msum0=max(tree[pos].msum0,tree[lson].rsum0+tree[rson].lsum0);
    tree[pos].msum1=max(tree[pos].msum1,tree[lson].rsum1+tree[rson].lsum1);
    int l1=tree[lson].r-tree[lson].l+1;
    int l2=tree[rson].r-tree[rson].l+1;
    if(l1==tree[lson].lsum0)
        tree[pos].lsum0+=tree[rson].lsum0;
    if(l1==tree[lson].lsum1)
        tree[pos].lsum1+=tree[rson].lsum1;
    if(l2==tree[rson].rsum0)
        tree[pos].rsum0+=tree[lson].rsum0;
    if(l2==tree[rson].rsum1)
        tree[pos].rsum1+=tree[lson].rsum1;
    tree[pos].sum=tree[lson].sum+tree[rson].sum;

}
inline void pushdown(int pos)
{
    int x=tree[pos].lazy;
    if(x==0)
    {
        tree[lson].lazy=0;
        tree[lson].sum=0;
        tree[lson].lsum1=tree[lson].rsum1=tree[lson].msum1=0;
        tree[lson].lsum0=tree[lson].rsum0=tree[lson].msum0=tree[lson].r-tree[lson].l+1;

        tree[rson].lazy=0;
        tree[rson].sum=0;
        tree[rson].lsum1=tree[rson].rsum1=tree[rson].msum1=0;
        tree[rson].lsum0=tree[rson].rsum0=tree[rson].msum0=tree[rson].r-tree[rson].l+1;

    }
    else if(x==1)
    {
        tree[lson].lazy=1;
        tree[lson].sum=tree[lson].r-tree[lson].l+1;
        tree[lson].lsum1=tree[lson].rsum1=tree[lson].msum1=tree[lson].r-tree[lson].l+1;
        tree[lson].lsum0=tree[lson].rsum0=tree[lson].msum0=0;

        tree[rson].lazy=1;
        tree[rson].sum=tree[rson].r-tree[rson].l+1;
        tree[rson].lsum1=tree[rson].rsum1=tree[rson].msum1=tree[rson].r-tree[rson].l+1;
        tree[rson].lsum0=tree[rson].rsum0=tree[rson].msum0=0;
    }
    else if(x==2)
    {
        if(tree[lson].l!=tree[lson].r)
            pushdown(lson);
        tree[lson].lazy=2;
        tree[lson].sum=tree[lson].r-tree[lson].l+1-tree[lson].sum;
        int t=tree[lson].lsum1;
        tree[lson].lsum1=tree[lson].lsum0;
        tree[lson].lsum0=t;

        t=tree[lson].rsum1;
        tree[lson].rsum1=tree[lson].rsum0;
        tree[lson].rsum0=t;

        t=tree[lson].msum1;
        tree[lson].msum1=tree[lson].msum0;
        tree[lson].msum0=t;

        if(tree[rson].l!=tree[rson].r)
            pushdown(rson);
        tree[rson].lazy=2;
        tree[rson].sum=tree[rson].r-tree[rson].l+1-tree[rson].sum;
        t=tree[rson].lsum1;
        tree[rson].lsum1=tree[rson].lsum0;
        tree[rson].lsum0=t;

        t=tree[rson].rsum1;
        tree[rson].rsum1=tree[rson].rsum0;
        tree[rson].rsum0=t;

        t=tree[rson].msum1;
        tree[rson].msum1=tree[rson].msum0;
        tree[rson].msum0=t;
    }
    tree[pos].lazy=-1;
}
void build(int l,int r,int pos)
{
    tree[pos].l=l;
    tree[pos].r=r;
    if(l==r)
    {
        int x;
        scanf("%d",&x);
        tree[pos].lazy=-1;
        tree[pos].msum0=!x;
        tree[pos].msum1=x;
        tree[pos].lsum0=!x;
        tree[pos].lsum1=x;
        tree[pos].rsum0=!x;
        tree[pos].rsum1=x;
        tree[pos].sum=x;
        return ;
    }
    int mid=tree[pos].mid();
    build(l,mid,lson);
    build(mid+1,r,rson);
    tree[pos].lazy=-1;
    pushup(pos);
}
void update(int l,int r,int x,int pos)
{
    if(l==tree[pos].l&&r==tree[pos].r)
    {
        if(x==0)
        {
            tree[pos].lazy=0;
            tree[pos].sum=0;
            tree[pos].lsum1=tree[pos].rsum1=tree[pos].msum1=0;
            tree[pos].lsum0=tree[pos].rsum0=tree[pos].msum0=tree[pos].r-tree[pos].l+1;
        }
        else if(x==1)
        {
            tree[pos].lazy=1;
            tree[pos].sum=tree[pos].r-tree[pos].l+1;
            tree[pos].lsum1=tree[pos].rsum1=tree[pos].msum1=tree[pos].r-tree[pos].l+1;
            tree[pos].lsum0=tree[pos].rsum0=tree[pos].msum0=0;
        }
        else
        {
            if(l!=r)          //是1,或0的时候可以直接覆盖,但如果是2的话必须向下更新,,本质~因为下面的状态随上面的变化,
                pushdown(pos);
            tree[pos].lazy=2;
            tree[pos].sum=tree[pos].r-tree[pos].l+1-tree[pos].sum;
            int t=tree[pos].lsum1;
            tree[pos].lsum1=tree[pos].lsum0;
            tree[pos].lsum0=t;

            t=tree[pos].rsum1;
            tree[pos].rsum1=tree[pos].rsum0;
            tree[pos].rsum0=t;

            t=tree[pos].msum1;
            tree[pos].msum1=tree[pos].msum0;
            tree[pos].msum0=t;
        }
        return ;
    }
    pushdown(pos);
    int mid=tree[pos].mid();
    if(r<=mid)
        update(l,r,x,lson);
    else if(l>mid)
        update(l,r,x,rson);
    else
    {
        update(l,mid,x,lson);
        update(mid+1,r,x,rson);
    }
    pushup(pos);
}
int queryR(int l,int r,int pos)
{
    if(r-l+1>=tree[pos].rsum1)
        return tree[pos].rsum1;
    else
        return r-l+1;
}
int queryL(int l,int r,int pos)
{
    if(r-l+1>=tree[pos].lsum1)
        return tree[pos].lsum1;
    else
        return r-l+1;
}
int query(int l,int r,int x,int pos)
{
    if(l==tree[pos].l&&r==tree[pos].r)
    {
        if(x==3)
            return tree[pos].sum;
        else
            return tree[pos].msum1;
    }
    pushdown(pos);
    int mid=tree[pos].mid();
    if(x==3)
    {
        if(r<=mid)
            return query(l,r,x,lson);
        else if(l>mid)
            return query(l,r,x,rson);
        else
            return query(l,mid,x,lson)+query(mid+1,r,x,rson);
    }
    else
    {
        if(r<=mid)
            return query(l,r,x,lson);
        else if(l>mid)
            return query(l,r,x,rson);
        else
        {
            int res=query(l,mid,x,lson);
            res=max(res,query(mid+1,r,x,rson));
            res=max(res,queryR(l,mid,lson)+queryL(mid+1,r,rson));
            return res;
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        build(1,n,1);
        int i;
        for(i=0;i<m;i++)
        {
            int a,b,x;
            scanf("%d%d%d",&x,&a,&b);
            a++,b++;
            if(x<=2)
                update(a,b,x,1);
            else
            {
                int res=query(a,b,x,1);
                printf("%d\n",res);
            }
        }
    }
    return 0;
}


华为OD机试真题 新系统 - WIFI设备网络规划 (Java/Py/C/C++/Js/Go) 本文整理华为 OD 机试新系统机考真题库,涵盖高频考点精析与完整题目内容,提供 C 语言、Java、C++、Python、Go、JavaScript 多语言源码实现,搭配详细解题思路讲解,并支持在线 OJ 刷题练习,助力高效备考华为 OD 机试新系统。 阅读详情

相关推荐

Arch Linux双系统安装避坑指南:从Windows分区到桌面环境全流程

本文提供了一份详尽的Arch Linux与Windows双系统安装避坑指南。内容涵盖从安装前的UEFI环境确认、BitLocker处理、分区规划,到Live环境进入、基础系统安装、GRUB引导配置,再到显卡驱动安装、KDE/GNOME桌面环境部署及中文化设置的全流程。重点解决了双系统安装中的核心痛点,帮助用户在不破坏现有Windows系统的前提下,顺利完成Arch Linux的安装。

nice1的博客 535

POJ 3667 Hotel 区间合并 线段树+懒标记

Description The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has n...

zhaohaibo的博客 455

【WireShark】WireShark windows平台编译 问题解决

最近工作中需要基于wireshark做二次开发,在windows平台构建过程中 遇到了找不到Glib库的问题,具体报错如下: Working in D:\WorkSpace\WIRESHARK\wiresharksource\wireshark-win64-libs Tag 2021-08-14 not found. Refreshing. Downloading https://anonsvn.wireshark.org/wireshark-win64-libs/tags/2021-08-14/pac

qq_35456540的博客 1546

HDU-3397-线段树区间合并(巧用lazy标记)

! 题目链接 题意 ​ 给出01区间 5种操作 ​ 0就是区间全置0 ,1区间全置1,2 区间反转0-1、1-0 ,3就是求区间有多少个1,4就是求最大连续1的长度 题解 我们可以维护0和1的左连续,右连续,最大连续 然后,有多少个1,我们直接维护就可以,就是左右1的和 然后,主要是区间反转 和 区间置01的关系 ,因为传递lazy的时候,他们直接有关系 反转是一个lazy 01,也是一个...

qiannianlaoyao‘s Blog 355

从零编写linux0.11 - 第二章 内核初始化

编程环境:Ubuntu Kylin 16.04 代码仓库:https://gitee.com/AprilSloan/linux0.11-project linux0.11源码下载(不能直接编译,需进行修改) 1.添加内核 进入内核后也不是马上进入main函数,上一章只是暂时设置gdt,此外还要设置idt和其他的一些初始化操作,这些内容也要使用汇编进行编写,此处采用AT&T格式的汇编。 以下为head.s的内容,为了简单起见,内容还是一个死循环。 .globl startup_32 startup_3

皓空Fly的博客 1266

STM32F103C8T6通过ESP8266连接阿里云物联网平台(附代码)

STM32F103C8T6连接阿里云物联网平台(1)—阿里云lot Studio控制 Web开发 分享一下自己使用stm32f103c8t6通过ESP_01模块连接阿里云物联网平台,实现温湿度上传和控制命令下达的过程,能力有限,用的是最简单的方法,如有错误,多多担待。 一、硬件选型 1、 stm32f103c8t6 2、ESP_01 wifi模块 3、其他 二、硬件连接 WSP_01 STM32F103C8T6 RXD PA2 TXD PA3 RES PA4 VCC 3.3

weixin_A13253323604 3万+

HDU - 3397(线段树区间合并,01覆盖)

链接 题意 有5种操作 op = 0 ,改变[a,b]区间值全为0 op = 1 ,改变[a,b]区间值全为1 op = 2 ,改变[a,b]区间值翻转,0 --> 1 ,1 --> 0 op = 3,,查询[a,b]区间所有1的个数 op =4,查询[a,b]区间最长连续1的个数 思路 首先很明显需要用线段树来维护区间信息, 线段树维护的信息 int sum[man<&lt...

nofuck的博客 310

新能源知识库(68)复叠压缩式热泵蒸汽系统介绍

复叠压缩式热泵蒸汽系统通过多级压缩技术将低品位热能转化为高品位蒸汽,在汽车电镀场景中实现了高效、精准的能源利用。随着超高温工质与智能联供系统的发展,该技术将深度赋能电镀行业的高质量可持续发展。​:±1℃控温保障镀层均匀性,提升产品良率;多台复叠热泵+储热装置(如纺织厂6台热泵)复叠热泵+余热回收+智能控制(化工厂案例)​:无燃烧设计契合汽车行业ESG目标。单台高温热泵机组(如92P型号)复叠压缩式热泵蒸汽系统以。67.4万元(↓22%)600万–1200万元。事故率 ↓90%​​。150万–600万元。

竹君子之家 1423

HDU - 3397 Sequence operation(线段树+区间合并)

题目链接:点击查看 题目大意:给定一个初始的数列,然后依次进行m次操作: 0 a b:将闭区间[a,b]内的点都变为0 1 a b:将闭区间[a,b]内的点都变为1 2 a b:将闭区间[a,b]内的点1变为0,0变为1(相当于取异或) 3 a b:查询闭区间[a,b]内有多少个1 4 a b:查询闭区间[a,b]内的最大连续的1的长度 题目分析:操作1、2、4是最简单的线段树操作,区...

Falcon的博客 442

利用Ghidra与SVD插件实现STM32固件深度逆向分析

本文详细介绍了如何利用Ghidra逆向工程框架结合SVD插件,实现对STM32固件(.bin文件)的深度逆向分析。通过加载描述芯片外设寄存器的SVD文件,Ghidra能将晦涩的硬件地址操作转换为可读的寄存器符号,极大提升了对嵌入式固件中通信协议、安全校验等关键逻辑的分析效率。文章涵盖了从Java环境搭建、工具配置到实战逆向解析的完整流程。

peach的博客 945

行业变革下的功能安全落地痛点3:高阶智驾安全责任转移 —— 从 “人为中心” 到 “机器主责” 的产业阵痛

文章围绕高阶智驾(L3 级)落地挑战,探讨安全责任从 “人控” 向 “机控” 转移的本质、技术短板导致的责任模糊、全球法规实践及技术 - 法规 - 保险的破局路径。

my9111526 126

HDU3397(Sequence operation)线段树解法

                                       Sequence operation                        Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)                                  ...

snayf的博客 356

华为OD机试真题 新系统 9月16号 【统计特殊数字】

华为OD新系统机试真题【统计特殊数字】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【统计特殊数字】。

qq_45776114的博客 774

HDU 3397 Sequence operation (线段树+区间合并+成段更新+多种操作)

题意:有N个为0或为1的数,有M个操作,操作有5种类型。(1)“0 a b”,表示将区间[a,b]范围内的数全部置0。(2)“1 a b”,表示将区间[a,b]内的数全部置1。(3)“2 a b”,表示将区间[a,b]内的数0变成1,1变成0。(4)“3 a b”,表示查询[a,b]范围内1的数。(5)“4 a b”,表示查询[a,b]范围内最长的连续的1。 题解:线段树+区间合并+成段更新 从昨天晚上wa到今天中午,终于a了。 说明一下变量。 sumsumsum:记录连续数字1。lsumlsumlsum:

gongyuandaye的博客 243

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

HDU - 3397 Sequence operation(线段树)

这个题确实不该说难,

Hardbird 771

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

HDU-3397 Sequence operation

Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description lxhgww got a sequence contains n characters which are all '0's or '

JSure的代码库 903

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

hdu-3397 Sequence operation 线段树多种标记

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3397 题目大意: 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的长度 解题思路: 线段树多种标记。 需要处理的东西比较多: 做题的时...

weixin_34413802的博客 160

HDU 3397 Sequence operation(线段树区间合并)

题意: 0 a b将区间[a,b]所有数全部变成0 1 a b将区间[a,b]所有数全部变成1 2 a b将区间[a,b]中所有数0 1互换,0变1,1变0 3 a b输出区间[a,b]中1的个数 4 a b输出区间[a,b]中最长连续1的个数 解析: 涉及到线段树的多种操作。 mxL[0]表示左边最长连续0的个数 mxR[0]表示右边最长连续0的个数

小G的ACM之路 627

HDU 3397 线段树 双懒惰标记

这个是去年遗留历史问题,之前思路混乱,搞了好多发都是WA,就没做了 自从上次做了大白书上那个双重懒惰标记的题目,做这个就思路很清晰了 跟上次大白上那个差不多,这个也是有一个sets标记,代表这个区间全部置为0或者1,没有置位的时候为-1 还有个rev标记,代表翻转操作,0代表当前不翻,1代表当前翻 要注意一下优先级,发现有不同的弄法,我是这个弄得,有set操作的时候,set标记设...

weixin_30653023的博客 124

HDU 3397 Sequence operation (线段树)

思路:和POJ3225有点像,但是多了那么些操作。对于区间1的个数和翻转情况,这都是可以用懒惰标记解决的。对于连续1的个数,需要区间合并。具体还是看注释吧。 #include #include #include #include using namespace std; #define maxn 100005 struct SegTree { int l,r; int o

BehappyXiang的专栏 859

HDU - 3397 Sequence operation (线段树,区间修改,亦或,查询,以及最长连续的1)

Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9078    Accepted Submission(s): 2765   Problem Description lxhgww got a ...

pxlsdz的博客 435

HDU 3397 Sequence operation(线段树区间染色加区间合并)

妈的调了两天终于过了。。。我好菜啊。 题意 对长度为n的序列执行q种操作, 0:把区间内的值都置为0; 1:把区间内的值都置为1; 2:把区间内的0都置为1,区间内的1都置为0; 3:查询区间里1的个数; 4:查询区间里最长的连续为1的区间的长度; 题解 显然,线段树区间更新区间查询可解此题,具体是: 维护懒标标记set,区间里1的个数sum1,区间左端点l,区间右端点r,区间...

weixin_34104341的博客 126

hdu 3397 Sequence operation (线段树+区间合并+双Lazy标记)

给你一个长度为n的0、1序列,然后对该序列进行m次操作(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的数目。 刚开始做的时候就想用两个Lazy标记,一个覆盖标记,一个异或

~飞呀,飞~ 1066

HDU 3397 Sequence operation(线段树好题)

题目链接:Click here~~ 题意: 很给力的线段树题,感觉对帮助理解线段树十分有帮助。写了 200 行,debug了 2 小时。好爽。 有一个数列,然后5种操作: 1、将 [a,b] 中所有数变成0。 2、将 [a,b] 中所有数变成1。 3、将 [a,b] 中所有数取反。 4、询问 [a,b] 中 1 的个数。 5、询问 [a,b] 中

nyist_xiaod 938

HDU 3397 双lazy标记的问题

题目大意 对一个只有0和1的序列,支持以下几种操作1.将区间所有的值变成12.将区间所有的值变为03.将区间的0和1翻转(0变成1 1变成0)4.求区间中1的个数5.求区间连续最长的1的个数 http://vjudge.net/problem/viewProblem.action?id=14689 整整一下午。。。简直把自己修改的都要哭了 lazy标记有先后关系,如to[]覆盖后...

weixin_30869099的博客 68

【专题】线段树

单点更新 最最基础的线段树,只更新叶子节点,然后把信息用PushUP(int r)这个函数更新上来。 hdu1166 敌兵布阵 线段树 hdu 1166 敌兵布阵 单点更新区间求和 hdu1754 I Hate It 线段树 hdu 1754 I Hate It 单点更新 区间求最值 hdu1394 Minimum Inversion Number hdu 1394

Azarath Metrion Zinthos 1092
上一篇: hdu3308 线段树 区间合并
下一篇: hdu 2871 线段树+区间合并 好题
JustSteps
博客等级 码龄14年 48粉丝 210原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值