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

news2024/11/24 21:08:10

补题链接: 码蹄集

一道经典线段树板子题。

区间修改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.coloradmin.cn/o/1871042.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

03逻辑门电路

分立门电路&#xff1a; 集成门电路&#xff1a; TTL门电路 MOS门电路&#xff1a;NMOS门电路、PMOS门电路、CMOS门电路 BICMOS门电路&#xff1a;CMOS的高输入阻抗和TTL的高放大倍数的结合 向更低功耗、更高速度发展 MOS管的Rdson在可变电阻区的阻值也一般会小于1000欧姆 …

【自动化测试】Selenium自动化测试框架 | 相关介绍 | Selenium + Java环境搭建 | 常用API的使用

文章目录 自动化测试一、selenium1.相关介绍1.Selenium IDE2.Webdriverwebdriver的工作原理&#xff1a; 3.selenium Grid 2.Selenium Java环境搭建3.常用API的使用1.定位元素2.操作测试对象3.添加等待4.打印信息5.浏览器的操作6.键盘事件7.鼠标事件8.定位一组元素9.多层框架定…

prompt:我是晚餐盲盒,只要你问出“今晚吃什么”我就将为你生成美妙的食物推荐。

使用方法&#xff1a;在ChatGP粘贴下面提示词模型&#xff0c;点击输出。然后再问“晚餐有什么好吃的&#xff1f;”&#xff0c;AI输出丰种食物供你选择。抽到什么吃什么&#xff0c;极大的解决选择困难的问题。 客户需要生成1000条俏皮灵动&#xff0c;趣味盎然&#xff0c;比…

VS2019安装插件image watch

image watch的作用&#xff1a; &#xff08;1&#xff09;放大、缩小图像&#xff1b; &#xff08;2&#xff09;将图像保存到指定的目录&#xff1b; &#xff08;3&#xff09;显示图像大小、通道数&#xff1b; &#xff08;4&#xff09;拖拽图像&#xff1b; &…

动态流体工厂大屏

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 namespace 动态流体工厂大屏 {public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){Task.Run(() >{while (true){this.Invoke(() >…

基于51单片机电子称—串口显示

基于51单片机电子称设计 &#xff08;仿真&#xff0b;程序&#xff09; 功能介绍 具体功能&#xff1a; 1.矩阵键盘组成按键&#xff0c;输入价格结算、打印&#xff1b; 2.用滑动变阻器和ADC0832模拟称重&#xff1b; 3.LCD1602可以显示重量、单价和总价&#xff1b; 4.…

关于新零售的一些思考

本文作为2024上半年大量输入之后的核心思考之一。工作到一定阶段之后&#xff0c;思考的重要性越来越高&#xff0c;后续会把自己的个人思考记录在这个新系列《施展爱思考》。背景是上半年面临业务转型从电商到新零售&#xff0c;本文是相关大量输入之后的思考&#xff0c;对新…

vue2中的组件自定义事件

1.绑定事件: <组件 :自定义名称"方法" /> 2.调用 this.$emit(方法,参数) 3.关闭 this.$off(方法) 案例: 1.提前准备好组件 Student组件 <template><div class"student"><h1>学校名称:{{ st…

JAVA每日作业day6.27

ok了家人们&#xff0c;今天学习了内部类&#xff0c;话不多说我们一起看看吧。 一&#xff0c;内部类 1.1 内部类概述 将一个类 A 定义在另一个类 B 里面&#xff0c;里面的那个类 A 就称为 内部 类 &#xff0c; B 则称为 外部类 。 内部类分为成员内部类与局部内部类。 1…

修改 app id - 鸿蒙 HarmonyOS Next

修改项目 app id 后通过真机 build run 的时候抛出了如下异常; 项目中更改后的配置与真机的不匹配; {app: {bundleName: "com.xxxxxx.xxx_harmony",vendor: "xxxxxx",versionCode: 1,versionName: "3.5.00",icon: "$media:app_icon",…

9.二维数组的遍历和存储

二维数组的遍历和存储 二维数组的遍历 二维数组a[3][4],可分解为三个一维数组,其数组名分别为: 这三个一维数组都有4个元素,例如:一维数组a[0]的 元素为a[0][0],a[0][1],a[0][2],a[0][3]。所以遍历二维数组无非就是先取出二维数组中得一维数组, 然后再从一维数组中取出每个元…

Open AI限制来袭?用上这个工具轻松破局!

【导语】近日&#xff0c;AI领域掀起了一场不小的波澜。Open AI宣布&#xff0c;从7月9日起&#xff0c;将对部分地区的开发者实施API调用限制。这一消息对于许多依赖Open AI技术的国内初创团队来说&#xff0c;无疑是一个沉重的打击。 对于这些团队而言&#xff0c;Open AI的A…

Spring相关面试题(三)

29 如何在所有的BeanDefinition注册完成后&#xff0c;进行扩展 Bean工厂的后置处理器&#xff0c;在所有的Bean注册完成后&#xff0c;就被执行。 public class A implements BeanFactoryPostProcessor {private String name "a class";private B b; ​public St…

如何使用ig507金融数据库的股票接口,股票API来获取MACD指标

一、MACD指标简介 MACD&#xff08;Moving Average Convergence Divergence&#xff0c;移动平均收敛/发散&#xff09;是一种趋势跟踪动量指标&#xff0c;用于分析股票或其他金融产品的价格趋势。MACD由两部分组成&#xff1a;差离值&#xff08;DIF&#xff09;和信号线&am…

麒麟系统安装MySQL

搞了一整天&#xff0c;终于搞定了&#xff0c;记录一下。 一、背景 项目的原因&#xff0c;基于JeecgBoot开发的系统需要国产化支持&#xff0c;这就需要在电脑上安装MySQL等支撑软件。 国产化项目的操作系统多是麒麟系统&#xff0c;我的系统如下&#xff1a; arm64架构。…

杀手级AI应用前瞻,一文带你了解8个ai大语言模型

一、大模型解析&#xff08;LLM、MLLM、GLM&#xff09; 基础概念&#xff1a; Transformer&#xff1a;ChatGPT的核心结构是Transformer&#xff0c;这是一种采用自注意力机制的深度学习模型。通过自注意力机制&#xff0c;Transformer能够理解输入文本的上下文信息&#xf…

当中年男人的觉越来越少 他突然半夜买台电脑(30+岁仿真工程师买电脑心得)

仿真工程师的购机分析&#xff0c;游戏本、移动工作站还是台式机&#xff1f; 认清自己的需求。 现状。现在有一个19年买的华为matebook14、i5第八代低压U&#xff0c;8G内存。还好有SSD当虚拟内存&#xff0c;要不开网页估计都得卡住。媳妇还有台i7、16G的matebook&#xff…

劳易测安全技术速递:滑动式输送系统出入口安全防护

汽车总装车间的滑动式输送系统用于搬运可以调整高度和位置的工作平台&#xff0c;大幅提升了汽车装配线的作业效率。但传统的安全解决方案在面对物料尺寸变动时&#xff0c;往往无法精准检测到人员位置&#xff0c;导致安全隐患。 针对滑动式输送系统出入口的安全防护&#xff…

OpenCV使用forEach的方式来遍历像素值

opencv 4.x新增了forEach的方式遍历像素值&#xff0c;比传统方式略快一些。因为它本身是使用多线程并行的方法来遍历的。从opencv源码能看到这句话&#xff1a; parallel_for_(cv::Range(0, LINES), PixelOperationWrapper(reinterpret_cast<Mat_<_Tp>*>(this), …

Spring框架学习笔记(本地印象笔记搬运)(整理中)

1、背景 Spring作为Java Web开发使用最频繁的框架&#xff0c;具有非常高的学习价值&#xff0c;在Spring框架源码中包含了很多设计模式&#xff08;单例、原型、代理、观察者等&#xff09;&#xff0c;读懂这些源码有助于拓宽开发思路&#xff0c;同时也能提高后端排查错误的…