2024百度之星第二场-小度的01串

补题链接: 码蹄集

一道经典线段树板子题。

区间修改01置换,区间查询子串权值。

唯一区别,权值要求的是相邻字符都不同所需修改的最小字符个数。

我们在线段树节点上分别维护当前连续区间:

奇数位是0的个数(j0),奇数位是1的个数(j1)。

偶数位是0的个数(o0),偶数位是1的个数(o1)。

以及当前区间的答案ans,是否往子区间延迟lazy。

考虑如何通过维护的信息进行pushup。

如图所示:

黑色三角:表示虚线左右子区间各自的奇数位置

红色三角:表示合并后奇数位置。

当左区间是奇数时,黑色三角=红色三角

要想变成10间断,要不变成101010...,要不变成0101010....

令 ls是左区间,rs是右区间。

如果变成101010,那就是ans=tr[ls].j0+tr[ls].o1+tr[rs].j0+tr[rs].o1

如果变成010101,那就是ans=总长度-(tr[ls].j0+tr[ls].o1+tr[rs].j0+tr[rs].o1)

取个max就行。

但当左区间不是奇数,黑色三角!=红色三角

如果变成101010,那就是ans=tr[ls].j0+tr[ls].o1+tr[rs].j1+tr[rs].o0

如果变成010101,那就是ans=总长度-(tr[ls].j0+tr[ls].o1+tr[rs].j1+tr[rs].o0)

到这里我们就解决了从子区间到大区间的pushup问题,代码如下所示。
 

void pushup(int p){
	int len=tr[p].r-tr[p].l+1;
	int lenls=tr[ls].r-tr[ls].l+1;
	if (lenls&1){
		int sum=tr[ls].j0+tr[ls].o1+tr[rs].j1+tr[rs].o0;
		tr[p].ans=min(sum,len-sum);
		tr[p].j0=tr[ls].j0+tr[rs].o0;
		tr[p].j1=tr[ls].j1+tr[rs].o1;
		tr[p].o0=tr[ls].o0+tr[rs].j0;
		tr[p].o1=tr[ls].o1+tr[rs].j1;
	}
	else{
		int sum=tr[ls].j0+tr[ls].o1+tr[rs].j0+tr[rs].o1;
		tr[p].ans=min(sum,len-sum);
		tr[p].j0=tr[ls].j0+tr[rs].j0;
		tr[p].j1=tr[ls].j1+tr[rs].j1;
		tr[p].o0=tr[ls].o0+tr[rs].o0;
		tr[p].o1=tr[ls].o1+tr[rs].o1;
	}
}

pushdown问题,其实比较常规,就是01置换,异或一下就行,代码如下所示。

void pushdown(int p){
	tr[ls].laz=tr[ls].laz^tr[p].laz;
	tr[rs].laz=tr[rs].laz^tr[p].laz;
	swap(tr[ls].j0,tr[ls].j1);
	swap(tr[ls].o0,tr[ls].o1);
	swap(tr[rs].j0,tr[rs].j1);
	swap(tr[rs].o0,tr[rs].o1);
	tr[p].laz=0;
}

当我们维护的东西不只是ans的时候,query需要返回一个结构体,因为当查询的x,y在左右区间都有的时候,需要向上手动合并。

全部问题解决完后,完整代码如下所示。 

#include<bits/stdc++.h>
using namespace std;
const int N=2e6+5;
#define ls p<<1
#define rs p<<1|1
struct tree{
	int l,r;
	int j0,j1,o0,o1;
	int laz,ans;
}tr[N];
char s[N];
int n,q;
void pushup(int p){
	int len=tr[p].r-tr[p].l+1;
	int lenls=tr[ls].r-tr[ls].l+1;
	if (lenls&1){
		int sum=tr[ls].j0+tr[ls].o1+tr[rs].j1+tr[rs].o0;
		tr[p].ans=min(sum,len-sum);
		tr[p].j0=tr[ls].j0+tr[rs].o0;
		tr[p].j1=tr[ls].j1+tr[rs].o1;
		tr[p].o0=tr[ls].o0+tr[rs].j0;
		tr[p].o1=tr[ls].o1+tr[rs].j1;
	}
	else{
		int sum=tr[ls].j0+tr[ls].o1+tr[rs].j0+tr[rs].o1;
		tr[p].ans=min(sum,len-sum);
		tr[p].j0=tr[ls].j0+tr[rs].j0;
		tr[p].j1=tr[ls].j1+tr[rs].j1;
		tr[p].o0=tr[ls].o0+tr[rs].o0;
		tr[p].o1=tr[ls].o1+tr[rs].o1;
	}
}
void pushdown(int p){
	tr[ls].laz=tr[ls].laz^tr[p].laz;
	tr[rs].laz=tr[rs].laz^tr[p].laz;
	swap(tr[ls].j0,tr[ls].j1);
	swap(tr[ls].o0,tr[ls].o1);
	swap(tr[rs].j0,tr[rs].j1);
	swap(tr[rs].o0,tr[rs].o1);
	tr[p].laz=0;
}
void build(int p,int l,int r){
	tr[p].l=l;
	tr[p].r=r;
	tr[p].laz=0;
	if (l==r){
		tr[p].j0=0;
		tr[p].j1=0;
		if (s[l]=='0') tr[p].j0=1;
		else if (s[l]=='1') tr[p].j1=1;			
		tr[p].ans=0;
		return;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(p);
}
void update(int p,int x,int y){
	int l=tr[p].l,r=tr[p].r;
	if (x<=l&&r<=y){
		tr[p].laz=tr[p].laz^1;
		swap(tr[p].j0,tr[p].j1);
		swap(tr[p].o0,tr[p].o1);
		return;
	}
	if (tr[p].laz) pushdown(p);
	int mid=(l+r)>>1;
	if (x<=mid) update(ls,x,y);
	if (y>mid) update(rs,x,y);
	pushup(p);
}
tree query(int p,int x,int y){
	int l=tr[p].l,r=tr[p].r;
	if (x<=l&&r<=y){
		return tr[p];
	}
	if (tr[p].laz) pushdown(p);
	int mid=(l+r)>>1;
	if (y<=mid) return query(ls,x,y);
	else if (x>mid) return query(rs,x,y);
	else{
		struct tree T,a,b;
		a=query(ls,x,y);
		b=query(rs,x,y);
		T.l=a.l;
		T.r=b.r;
		int len=T.r-T.l+1;
		int lenls=a.r-a.l+1;
		if (lenls&1){
			int sum=a.j0+a.o1+b.j1+b.o0;
			T.ans=min(sum,len-sum);
			T.j0=a.j0+b.o0;
			T.j1=a.j1+b.o1;
			T.o0=a.o0+b.j0;
			T.o1=a.o1+b.j1;
		}
		else{
			int sum=a.j0+a.o1+b.j0+b.o1;
			T.ans=min(sum,len-sum);
			T.j0=a.j0+b.j0;
			T.j1=a.j1+b.j1;
			T.o0=a.o0+b.o0;
			T.o1=a.o1+b.o1;
		}
		return T;
	}
}
void co(){
	for (int i=1;i<=9;i++){
		cout<<tr[i].l<<" "<<tr[i].r<<" "<<tr[i].laz<<" "<<tr[i].ans<<"||";
		cout<<"S:";
		for (int j=1;j<=n;j++){
			cout<<s[j];
		}
		cout<<"\n";
		cout<<"奇数 0:"<<tr[i].j0<<"| 1:"<<tr[i].j1<<"|||";
		cout<<"偶数 0:"<<tr[i].o0<<"| 1:"<<tr[i].o1<<"\n";
	}
}
void work(){
	cin>>n>>q;
	for (int i=1;i<=n;i++) cin>>s[i];
	build(1,1,n);
	for (int i=1;i<=q;i++){
		int t,l,r;cin>>t>>l>>r;
		if (t==1) update(1,l,r);
		else cout<<query(1,l,r).ans<<"\n";	
	}
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	work();
	return 0;
} 
/*
10101
000
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/750540.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ROS1通信机制——以topic为例

ROS1 的通信机制 ROS1是一个分布式框架&#xff0c;为用户提供多节点&#xff08;进程&#xff09;之间的通信服务。 ROS1通信时有一个中心节点&#xff08;ROS Master&#xff09;&#xff0c;进行信息匹配等工作。 ROS1 的话题通信机制 通信链接&#xff1a;XML/RPC 信息传…

YOLOV8图像分割预测后输出mask图

训练一个yolov8后&#xff0c;用官方的预测脚本一般是&#xff1a; results model.predict(img_path, saveTrue, save_diroutput_folder) 运行此代码会直接在run里面生成一个文件夹&#xff0c;保存预测图像。如果要获取分割后的mask点&#xff0c;或mask的轮廓点&#xff0…

WIFI各版本的带宽

带宽的定义&#xff1a; 带宽在网络领域通常指信道带宽&#xff0c;即信号在频谱中占用的频宽&#xff0c;单位是MHz&#xff08;兆赫&#xff09;。在无线通信中&#xff0c;带宽越宽&#xff0c;能够传输的数据量越大&#xff0c;因此信道带宽直接影响着数据传输速率。WiFi标…

SKYDROID-C12—— 让美景近在眼前

C12是一款小型高清双光吊舱&#xff0c;使用新一代影像芯片&#xff0c;搭配高清无畸变摄像头&#xff0c;有效像素达到500万&#xff0c;拥有强悍的2K视频录制和拍照能力&#xff0c;支持数字变倍&#xff0c;随时随地捕捉清晰的图像&#xff0c;让远处美景近在眼前。

Clickhouse 的性能优化实践总结

文章目录 前言性能优化的原则数据结构优化内存优化磁盘优化网络优化CPU优化查询优化数据迁移优化 前言 ClickHouse是一个性能很强的OLAP数据库&#xff0c;性能强是建立在专业运维之上的&#xff0c;需要专业运维人员依据不同的业务需求对ClickHouse进行有针对性的优化。同一批…

【Android11】开机启动日志捕捉服务

一、前言 制作这个功能的原因是客户想要自动的记录日志中的报错和警告到设备的内存卡里面。虽然开发者模式中有一个“bug report” 会在/data/user_de/0/com.android.shell/files/bugreports/目录下生成一个zip包记录了日志。但是客户觉得这个日志很难获取到他们需要的信息&am…

Transformer教程之神经网络和深度学习基础

在当今的人工智能领域&#xff0c;Transformer已经成为了一个热门的词汇。它不仅在自然语言处理&#xff08;NLP&#xff09;领域取得了巨大的成功&#xff0c;还在计算机视觉等其他领域展现出了强大的潜力。然而&#xff0c;要真正理解Transformer&#xff0c;我们首先需要扎实…

希喂生骨肉冻干值得入手吗?拯救瘦弱、增强抵抗力最强主食测评!

希喂生骨肉冻干值得入手吗&#xff1f;很多小姐妹觉着自家猫咪太瘦了、体质不咋好&#xff0c;换季还敏感、掉毛、不吃东西&#xff0c;听说生骨肉冻干好吸收、营养好&#xff0c;可以改善体质、拯救瘦弱、增强抵抗力&#xff0c;为了图省事&#xff0c;开始盲入生骨肉冻干&…

Linux—进程与计划管理

目录 一、程序 二、进程 1、什么是进程 2、进程的特点 3、进程、线程、携程 3.1、进程 3.2、线程 3.3、携程 三、查看进程信息 1、ps -aux 2、ps -elf 3、top ​3.2、输出内容详解 3.2.1、输出第一部分解释 3.2.2、输出第二部分解释 4、pgrep 5、pstree 四、进…

The ‘textprediction‘ attribute will be removed in the future

页面标签不展示&#xff0c;明明是复制的&#xff0c;反复检查&#xff0c;眼睛都看瞎了&#xff0c;也没找到&#xff0c;最后还是看后台报错&#xff0c;The textprediction attribute will be removed in the future说什么要被废弃&#xff0c;但是好好的标签怎么会无缘无辜…

C语言 | Leetcode C语言题解之第191题位1的个数

题目&#xff1a; 题解&#xff1a; int hammingWeight(uint32_t n) {int ret 0;while (n) {n & n - 1;ret;}return ret; }

2024最新特种设备(锅炉作业)题库分享。

1.锅炉蒸发量大小是由(  )决定的。 A.压力的高低 B.受压元件多少 C.受热面积大小 答案:C 2.哪项不是自然循环的故障?&#xff08; &#xff09; A.停滞 B.倒流 C.下降管带汽 D.上升管带汽 答案:D 3.水冷壁被现代大型锅炉广泛采用的是(  )。 A.光管水冷壁 B.膜…

龙迅LT8711V TYPE-CDP 1.2转VGA芯片,内置MCU,成熟批量产品

龙迅LT8711V描述&#xff1a; LT8711V是一种高性能的Type-C/DP1.2到VGA转换器&#xff0c;设计用于连接USB Type-C源或DP1.2源到VGA接收器。LT8711V集成了一个DP1.2兼容的接收器&#xff0c;和一个高速三通道视频DAC。此外&#xff0c;还包括两个CC控制器&#xff0c;用于CC通…

SherlockChain:基于高级AI实现的智能合约安全分析框架

关于SherlockChain SherlockChain是一款功能强大的智能合约安全分析框架&#xff0c;该工具整合了Slither工具&#xff08;一款针对智能合约的安全工具&#xff09;的功能&#xff0c;并引入了高级人工智能模型&#xff0c;旨在辅助广大研究人员针对Solidity、Vyper和Plutus智…

个人支付系统实现

基础首页&#xff1a; 订单&#xff1a; 智能售卡系统 基于webmanworkerman开发 禁用函数检查 使用这个脚本检查是否有禁用函数。命令行运行curl -Ss https://www.workerman.net/check | php 如果有提示Function 函数名 may be disabled. Please check disable_functions in …

显卡GTX与RTX有什么区别?哪一个更适合玩游戏?

游戏发烧友们可能对游戏显卡并不陌生&#xff0c;它直接关系到游戏画面的流畅度、细腻程度和真实感。在众多显卡品牌中&#xff0c;英伟达的GTX和RTX系列显卡因其出色的性能而备受关注。 一、GTX与RTX的区别 架构差异 GTX系列显卡采用的是Pascal架构&#xff0c;这是英伟达在…

Redis 7.x 系列【7】数据类型之列表(List)

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 常用命令2.1 RPUSH2.2 LPUSH2.3 LRANGE2.4 LINDEX2.6 LREM2.7 LLEN2.8 LPOP…

AGI 远不止 ChatGPT!一文入门 AGI 通识及应用开发_通向agi之路网站使用什么开发的网站

AI 大语言模型进入爆发阶段 2022 年 12 月 ChatGPT 突然爆火&#xff0c;原因是其表现出来的智能化已经远远突破了我们的常规认知。虽然其呈现在使用者面前仅仅只是一个简单的对话问答形式&#xff0c;但是它的内容化水平非常强大&#xff0c;甚至在某些方面已经超过人类了&am…

WordPress Dokan Pro插件 SQL注入漏洞复现(CVE-2024-3922)

0x01 产品简介 WordPress Dokan Pro插件是一款功能强大的多供应商电子商务市场解决方案,功能全面、易于使用的多供应商电子商务平台解决方案,适合各种规模的电商项目。允许管理员创建一个多卖家平台,卖家可以注册账户并在平台上创建自己的店铺,展示和销售自己的产品。提供…

python API自动化(基于Flask搭建MockServer)

接口Mock的理念与实战场景: 什么是Mock: 在接口中&#xff0c;"mock"通常是指创建一个模拟对象来代替实际的依赖项&#xff0c;以便进行单元测试。当一个类或方法依赖于其他类或组件时&#xff0c;为了测试这个类或方法的功能&#xff0c;我们可以使用模拟对象来替代…