首页 > 其他分享 >hihocoder #1078 : 线段树的区间修改

hihocoder #1078 : 线段树的区间修改

时间:2023-05-29 19:35:53浏览次数:39  
标签:lc 1078 int 线段 hihocoder setv rc include sum


解题思路:基础的线段树区间修改


我按照书上敲的代码不知道为什么WA。。。



#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 1e5;
int n,q,l,r,_sum;
int setv[maxn<<2],sum[maxn<<2];

void maintain(int o,int L,int R)
{
	int lc = o*2, rc = o*2+1;
	sum[o] = 0;
	if(R > L){
		sum[o] = sum[lc] + sum[rc];
	}
	else sum[o] = setv[o];
}

void pushdown(int o)
{
	int lc = o*2, rc = o*2+1;
	if(setv[o] >= 0){
		setv[lc] = setv[rc] = setv[o];
		setv[o] = -1;
	}
}

void update(int o,int L,int R,int v)
{
	int lc = o*2, rc = 2*o+1;
	if(l <= L && R <= r){
		setv[o] = v;
	}
	else{
		pushdown(o);
		int M = (L + R) >> 1;
		if(l <= M) 
			update(lc,L,M,v);
		else maintain(lc,L,M);
		if(r > M)
			update(rc,M+1,R,v);
		else maintain(rc,M+1,R);
	}
	maintain(o,L,R);
}

void query(int o,int L,int R)
{
	if(setv[o] >= 0){
		_sum += setv[o] * (min(R,r) - max(L,l) + 1);
	}
	else if(l <= L && R <= r){
		_sum += sum[o];
	}
	else{
		int M = (L + R) >> 1;
		if(l <= M) query(o*2,L,M);
		if(r > M) query(o*2+1,M+1,R);
	}
}

int main()
{
	int v,f;
	scanf("%d",&n);
	memset(setv,-1,sizeof(setv));
	for(int i = 1; i <= n; i++)
	{
		scanf("%d",&v);
		l = r = i;
		update(1,1,n,v);
	}
	scanf("%d",&q);
	while(q--)
	{
		scanf("%d",&f);
		if(f == 1)
		{
			scanf("%d%d%d",&l,&r,&v);
			update(1,1,n,v);
		}
		else
		{
			scanf("%d%d",&l,&r);
			_sum = 0;
			query(1,1,n);
			printf("%d\n",_sum);
		}
	}
	return 0;
}



标签:lc,1078,int,线段,hihocoder,setv,rc,include,sum
From: https://blog.51cto.com/u_16143128/6373659

相关文章

  • hdu 2795(线段树)
    解题思路:这道题很难想到是用线段树,确实转化的很巧妙实际上,我们只需要利用线段树(记录1-h)维护哪个位置的剩余空间最大即可,即1,2,......,h是线段树的叶子节点,我们每次要找的就是叶子节点的剩余空间的最大值,只要能够想到这里就很容易啦。。另外如果h>n的话,就令h=n,否则就是类似于位置多......
  • hdu 1698(线段树区间更新)
    解题思路:线段树区间更新水题。#include<iostream>#include<cstdio>#include<cstring>usingnamespacestd;constintmaxn=100005;structseg{ intl,r,sum,lazy;}tree[maxn<<2];voidbuild(intl,intr,intu){ tree[u].l=l; tree[u].r=r; t......
  • hdu 5367(线段树+区间合并)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5367官方题解:对于求“高山脉”长度,可以利用线段树。树节点中保存左高度连续长度,左高度连续区间的高度,左高度连续区间的状态(即是否高于第一个高度不同的山),右高度连续长度,右高度连续区间的高度,右高度连续区间的状态,每段区间内的“......
  • 线段树学习总结
    线段树入门线段树的概念线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN)。而未优化的空间复杂度为2N,实际应用时一般还要开4N的数组......
  • RMQ 问题的两种实现办法(线段树查询和稀疏表(Sparse Table表)查询)
    引言RMQ算法(RangeMinimum/MaximumQuery)是静态区间极值查询的高效算法,在各种算法竞赛中常常出现,虽然不会单独拿出来做一个题,但是经常作为题的一部分。依据所需实现的不同性能可以有多种写法,这里主要讲基于线段树和稀疏表(SparseTable)的两种方法。线段树实现RMQ线段树是维护......
  • 可持久化线段树
    区间第K大板子(动态开点)intn,m;introot[N],idx;structnode{ intl,r; intcnt;}tr[N*40];voidpushup(intu){ tr[u].cnt=tr[tr[u].l].cnt+tr[tr[u].r].cnt;}voidinsert(intp,int&q,intl,intr,intx){ q=++idx,tr[q]=tr[p]; if(l==r)t......
  • 空间判断点是否在线段上
    空间判断点是否在线段上的原理以及实现目录1.概述2.详论3.参考1.概述判断点是否在线段上的算法非常简单,有很多种实现方式,总结一下我自己的实现。2.详论个人认为通过向量计算的方式是比较好的,因为可以保证在二维和三维的情况都成立。判断空间中点P是否......
  • 【CSP 202303-4】星际网络Ⅱ 【离散化+线段树】
    题目链接http://118.190.20.162/view.page?gpid=T162题意一个网络地址由\(n\)(\(n\leq512\),且是16的倍数)位二进制位组成(形如xxxx:xxxx:....:xxxx),有若干用户需要申请一些网络地址。有三种操作:申请。给出一个用户编号,和要查询的地址区间[L,R],若全都没有被申请过,或者......
  • 线段树学习笔记
    让我们来一步一步理解! 1.向上更新voidpush_up(intrt){//向上更新sum[rt]=sum[rt<<1]+sum[rt<<1|1];} 2.向下更新voidpush_down(intrt,intm){if(add[rt]){//若有标记,则将标记向下移动一层add[rt<<1]+=add[rt];add[rt......
  • 线段树均摊复杂度
    GSS4-CanyouanswerthesequeriesIV操作\(1\):\(a_i=\sqrt{a_i},i\in[l,r]\)操作\(2\):询问\(\sum_{i=l}^ra_i\)开根号无法使用tag的方式维护,因为开根号后不确定减去多少,无法维护\(\suma_i\)。\(a_i=2^{\loga_i}\),每次开根号后\(\loga_i\)会减半,操作\(\log\l......