首页 > 其他分享 >P3870 [TJOI2009] 开关

P3870 [TJOI2009] 开关

时间:2025-01-01 11:27:49浏览次数:3  
标签:idx int tre 开灯 开关 TJOI2009 区间 P3870 操作

题目描述

现有 nn 盏灯排成一排,从左到右依次编号为:11,22,……,nn。然后依次执行 mm 项操作。

操作分为两种:

  1. 指定一个区间 [a,b][a,b],然后改变编号在这个区间内的灯的状态(把开着的灯关上,关着的灯打开);
  2. 指定一个区间 [a,b][a,b],要求你输出这个区间内有多少盏灯是打开的。

灯在初始时都是关着的。

输入格式

第一行有两个整数 nn 和 mm,分别表示灯的数目和操作的数目。

接下来有 mm 行,每行有三个整数,依次为:cc、aa、bb。其中 cc 表示操作的种类。

  • 当 cc 的值为 00 时,表示是第一种操作。
  • 当 cc 的值为 11 时,表示是第二种操作。

aa 和 bb 则分别表示了操作区间的左右边界。

输出格式

每当遇到第二种操作时,输出一行,包含一个整数,表示此时在查询的区间中打开的灯的数目。

样例输入:

4 5
0 1 2
0 2 4
1 2 3
0 2 4
1 1 4

输出

1
2

父节点下放到子节点,当父节点没有懒标记时,直接return,出现懒标记时,说明子节点数据要更新了,对于开灯关灯,一个区间对于已经开灯的数量,再次操作后就是这个区间长-当前开灯数量就是再次开灯时的数量。例如(1,0,1,0)区间1-4两个灯开着,再次启动1-4按钮时,开灯数量就是4-当前开灯的数量(2)。然后把子节点懒标记取反。

void pushdown(int idx,int l,int r)
{
    //当前没有懒标记
	if(laz[idx]^1) return ;
	
	laz[idx<<1]^=1;
	laz[idx<<1|1]^=1; 
	int mid=(l+r)>>1;
	tre[idx<<1]=(mid-l+1)-tre[idx<<1];
	tre[idx<<1|1]=(r-mid)-tre[idx<<1|1];
	laz[idx]^=1;
}

update操作,若区间(l,r)∈(x,y)父节点直接懒标记,更新后的开灯数量=区间长-上一次开灯的数量,这一道题最重要的就是这一点tre[idx]=(r-l+1)-tre[idx];

void update(int idx,int l,int r,int x,int y)
{
	if(l>=x&&r<=y)
	{
		laz[idx]^=1;
		tre[idx]=(r-l+1)-tre[idx];
		return ;
	}
	pushdown(idx,l,r);
	int mid=(r+l)>>1;
	if(x<=mid) update(idx<<1,l,mid,x,y);
	if(mid<y) update(idx<<1|1,mid+1,r,x,y);
	
	tre[idx]=tre[idx<<1]+tre[idx<<1|1];
}

query直接写板子即可。

完整代码(注意若不是用结构体,数组的大小要最少开到4*N)

#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10;
int tre[N],laz[N],n,m; 
void build(int idx,int l,int r)
{
	if(l==r)
	{
		tre[idx]=0;
		laz[idx]=0;
		return ;
	}
	tre[idx]=tre[idx<<1]+tre[idx<<1|1];
}
void pushdown(int idx,int l,int r)
{
	if(laz[idx]^1) return ;
	
	laz[idx<<1]^=1;
	laz[idx<<1|1]^=1; 
	int mid=(l+r)>>1;
	tre[idx<<1]=(mid-l+1)-tre[idx<<1];
	tre[idx<<1|1]=(r-mid)-tre[idx<<1|1];
	laz[idx]^=1;
}
void update(int idx,int l,int r,int x,int y)
{
	if(l>=x&&r<=y)
	{
		laz[idx]^=1;
		tre[idx]=(r-l+1)-tre[idx];
		return ;
	}
	pushdown(idx,l,r);
	int mid=(r+l)>>1;
	if(x<=mid) update(idx<<1,l,mid,x,y);
	if(mid<y) update(idx<<1|1,mid+1,r,x,y);
	
	tre[idx]=tre[idx<<1]+tre[idx<<1|1];
}
int query(int idx,int l,int r,int x,int y)
{
	if(l>=x&&r<=y) 
	{
		return tre[idx];
	}
	
	pushdown(idx,l,r);
	int mid=(l+r)>>1,ans=0;
	if(x<=mid) ans+=query(idx<<1,l,mid,x,y);
	if(mid<y) ans+=query(idx<<1|1,mid+1,r,x,y);
	return ans;
}
int main()
{
   ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
   cin>>n>>m;
   build(1,1,n);
   while(m--)
   {
   	  int op,x,y;
   	  cin>>op>>x>>y;
   	  if(op==0) update(1,1,n,x,y);
   	  else cout<<query(1,1,n,x,y)<<endl;
   }
  return 0;
}

标签:idx,int,tre,开灯,开关,TJOI2009,区间,P3870,操作
From: https://blog.csdn.net/qq_73819342/article/details/144864745

相关文章

  • 自定义开关(switch)
    演示代码<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metaname="viewport"content="width=device-width,initial-scale=1.0"/><title>custom_switch&l......
  • 使用css3实现一个滑动开关
    创建一个滑动开关(toggleswitch)可以使用纯CSS3,主要利用伪类、复选框(checkbox)和一些基础的CSS样式。以下是一个简单的示例:HTML部分:<labelclass="switch"><inputtype="checkbox"id="toggle"><spanclass="slider"></span></label>......
  • 使用CSS3实现一个3D开关按钮,可左右滑动
    要创建一个3D开关按钮,我们可以使用CSS3的transform和transition属性,以及HTML和JavaScript来添加交互性。以下是一个简单的实现:HTML:<divclass="switch-container"><divclass="switch"><divclass="switch-button"></div></div&......
  • 闭环控制中的开关电源(BUCK)
    闭环控制中的开关电源(BUCK)是一种高效的直流-直流(DC-DC)转换器,其核心原理基于电感的储能特性和开关管的快速通断控制。一、工作原理BUCK电路又称降压电路,其工作原理如下:当开关管(如S或Q)驱动为高电平时,开关管导通,此时储能电感(如L)被充磁,流经电感的电流线性增加。同时,电容(如C)开始......
  • 36MT160-ASEMI开关电源整流方桥36MT160
    编辑:ll36MT160-ASEMI开关电源整流方桥36MT160型号:36MT160品牌:ASEMI封装:D-63特性:插件整流方桥正向电流:35A反向耐压:1600V恢复时间:>2000ns引脚数量:5芯片个数:4芯片尺寸:50MIL浪涌电流:500A漏电流:>10uA工作温度:-55℃~150℃包装方式:3k/盘;30k/箱备受欢迎的36MT160整流桥ASE......
  • Flutter进阶组件(3):SwitchListTile(开关列表项)
    SwitchListTile是一个包含开关(Switch)的列表项,非常适合用来创建带有标题、副标题以及开关的列表项,常用于设置界面,让用户可以轻松地开启或关闭某个功能。一、基本使用SwitchListTile(title:constText('EnableNotifications'),value:true,//开关的初始状态onChanged......
  • 开关电源中的高频振荡噪声及其抑制方法
    开关电源作为现代电子设备中不可或缺的电源模块,在提供稳定电压的同时,也会面临许多电磁兼容性(EMC)挑战。除了我们通常关注的差模噪声源和共模噪声源外,开关电源中还存在一些其他的高频噪声源,这些噪声源同样可能导致电磁干扰(EMI)问题,影响电路的正常工作,并可能违反电磁兼容标准。......
  • vue3 - vite 对于是否生成 xxx.js.map文件的开关设置-总结
    有3个办法可以设置不生成map文件1.package.json文件里的打包语句"build:docker":"vue-tsc--noEmit&&vitebuild--modedev",中,添加--noEmit参数,则不会生成map包2.vite.config.ts文件里的build.sourcemap属性,设置为false,则不会生成map包3.tsconfig.json文件里的c......
  • FS2115C是一款低噪声、恒定频率(1 2MHz)的开关电容器倍压器。
    一般描述(百度翻译)FS2115C是一款低噪声、恒定频率(1.2MHz)开关电容倍压器。它产生2.7V至5V输入的稳压输出电压,输出电流高达250mA。该PW5410A外部元件数量少(VIN和VOUT处有一个跨接电容器和两个小型旁路电容器),非常适合小型电池供电应用。新的电荷泵架构可在空载时保持......
  • 德普微一级代理 DP2601X SOP-7 带自供功能的多模式、恒压恒流原边控制功率开关
    主要特点带自供电功能,变压器无需辅助绕组具备快速启动功能启动时具有 Line BOP 功能集成 800V 高压功率 BJT±5% 恒流、恒压精度多模式原边控制方式工作无异音可调式线损补偿l 集成线电压和负载电压的恒流补偿集成完善的保护功能:   短路保护 (SLP) ......