hdu 4107当卡段树「建议收藏」

hdu 4107当卡段树

大家好,又见面了,我是全栈君。

其核心思想是记录最大的节点值和最低值,假设max<p要么min>=p时间,在节点只变化add值,不要子树遍历;否则,就往子树递归。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>

using namespace std;

const int maxn = 2e5+50;
int N, P;

struct node{
	int l, r, Min, Max, add;
	int mid() { return (l+r)/2; }
}tree[maxn<<2];

int p, n;
void buildTree(int l, int r, int rt)
{
	tree[rt].l = l;
	tree[rt].r = r;
	tree[rt].add = 0;
	tree[rt].Min = 0;
	tree[rt].Max = 0;
	if(l == r) return ;
	int mid = tree[rt].mid();
	buildTree(l, mid, rt<<1);
	buildTree(mid+1, r, rt<<1|1);
}

void update(int l, int r, int rt, int L, int R, int add)
{
	if(L <= l && R >= r)
	{
		if(tree[rt].Max < P)
		{
			tree[rt].add += add;
			tree[rt].Min += add;
			tree[rt].Max += add;
			return ;
		}
		else if(tree[rt].Min >= P)
		{
			tree[rt].add += 2*add;
			tree[rt].Min += 2*add;
			tree[rt].Max += 2*add;
			return ;
		}
	}
	if(tree[rt].add){
		tree[rt<<1].add += tree[rt].add;
		tree[rt<<1].Min += tree[rt].add;
		tree[rt<<1].Max += tree[rt].add; 
		tree[rt<<1|1].add += tree[rt].add;
		tree[rt<<1|1].Min += tree[rt].add;
		tree[rt<<1|1].Max += tree[rt].add;
		
		tree[rt].add = 0;
	}
	if(l == r) return ;
	int mid = tree[rt].mid();
	if(L <= mid) update(l, mid, rt<<1, L, R, add);
	if(R > mid) update(mid+1, r, rt<<1|1, L, R, add);
	
	tree[rt].Min = min(tree[rt<<1].Min, tree[rt<<1|1].Min);
	tree[rt].Max = max(tree[rt<<1].Max, tree[rt<<1|1].Max);
} 

void query(int l, int r, int rt)
{
	if(tree[rt].Min == tree[rt].Max){
		for(int i = l; i <= r; i ++)
			printf( i == N ? "%d\n" : "%d ", tree[rt].Min );
		return ;
	}
	if(tree[rt].add)
	{
		tree[rt<<1].add += tree[rt].add;
		tree[rt<<1].Min += tree[rt].add;
		tree[rt<<1].Max += tree[rt].add; 
		tree[rt<<1|1].add += tree[rt].add;
		tree[rt<<1|1].Min += tree[rt].add;
		tree[rt<<1|1].Max += tree[rt].add;
		
		tree[rt].add = 0;
	}	
	if(l == r) return ;
	int mid = tree[rt].mid();
	query(l, mid, rt<<1);
	query(mid+1, r, rt<<1|1);
}

int main()
{
	int n, m, p;
	int a, b, c;
	while(~scanf("%d%d%d", &n, &m, &p))
	{
		N = n;
		P = p;
		buildTree(1, n, 1);
		for(int i = 0; i < m; i ++)
		{
			scanf("%d%d%d", &a, &b, &c);
			update(1, n, 1, a, b, c);
		}
		query(1, n, 1);
	}
} 


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116662.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SVD的理解

    SVD的理解近一段时间一直在看推荐系统相关的内容 看到协同过滤的时候 有的大佬将协同过滤分成了三种情况 当然实际情况也许不止三种 来考虑并做了相互之间的比较 其中有一种就是基于 SVD 的协同过滤 当时看到这个是一脸的懵 就赶紧查了一下相关的资料恶补一下 记录在这 SVD 定义 首先 我们来看一下什么是 SVD 奇异值分解 SingularValu 以下简称 SVD 是在机器学习

    2025年10月16日
    2
  • django3.0异步_定时任务框架

    django3.0异步_定时任务框架celery介绍Celery是由Python开发、简单、灵活、可靠的分布式任务队列,是一个处理异步任务的框架,其本质是生产者消费者模型,生产者发送任务到消息队列,消费者负责处理任务。Celery侧重

    2022年8月7日
    6
  • JQuery 简单实现折叠菜单

    JQuery 简单实现折叠菜单

    2022年3月12日
    42
  • mysql主从复制跳过错误

    mysql主从复制跳过错误

    2021年6月1日
    86
  • js面试笔试–prototype详解

    js面试笔试–prototype详解对JavaScript中原型模式的理解一:什么是原型对象?有什么优点?   简单的来说,无论何时,我们创建的每一个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,这个对象包含了通过调用该构造函数所创建的对象共享的属性和方法。其实我们平常的叫法就是指:prototype就是通过该构造函数创建的某个实例的原型对象,但是其实prototype是每个构造函数的属性而已,只能说…

    2022年7月22日
    9
  • Idea激活码永久有效Idea2020.3.2激活码教程-持续更新,一步到位

    Idea激活码永久有效Idea2020.3.2激活码教程-持续更新,一步到位Idea激活码永久有效2020.3.2激活码教程-Windows版永久激活-持续更新,Idea激活码2020.3.2成功激活

    2022年6月17日
    64

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号