HDOJ 题目4107 Gangster(线段树)

本文介绍了一个关于两个帮派冲突的问题,其中一个帮派拥有一把能够对特定范围内成员造成伤害的魔法枪。文章通过一个数组来模拟这一过程,并利用线段树进行区间更新和查询操作,以高效地解决此问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Gangster

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2869    Accepted Submission(s): 728


Problem Description
There are two groups of gangsters fighting with each other. The first group stands in a line, but the other group has a magic gun that can shoot a range [a, b], and everyone in that range will take a damage of c points. When a gangster is taking damage, if he has already taken at least P point of damage, then the damage will be doubled. You are required to calculate the damage that each gangster in the first group toke.
To simplify the problem, you are given an array A of length N and a magic number P. Initially, all the elements in this array are 0.
Now, you have to perform a sequence of operation. Each operation is represented as (a, b, c), which means: For each A[i] (a <= i <= b), if A[i] < P, then A[i] will be A[i] + c, else A[i] will be A[i] + c * 2.
Compute all the elements in this array when all the operations finish.
 

Input
The input consists several testcases.
The first line contains three integers n, m, P (1 <= n, m, P <= 200000), denoting the size of the array, the number of operations and the magic number.
Next m lines represent the operations. Each operation consists of three integers a; b and c (1 <= a <= b <= n, 1 <= c <= 20).
 

Output
Print A[1] to A[n] in one line. All the numbers are separated by a space.
 

Sample Input
  
3 2 1 1 2 1 2 3 1
 

Sample Output
  
1 3 1
 

Source
 

Recommend
lcy   |   We have carefully selected several similar problems for you:   4102  4103  4105  4106  4108 
 

题目大意:输入n,m,p,给你一个有n个数的序列,开始都是0,然后后边m个操作,每个操作

g++过了,c++超时。。弱啊。。


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define N  200010
int n,m,p;
struct s
{
	int maxn,minn,cover;
}node[N*3];
void build(int l,int r,int tr)
{
	node[tr].maxn=node[tr].minn=node[tr].cover=0;
	int mid=(l+r)>>1;
	if(l==r)
		return;
	build(l,mid,tr<<1);
	build(mid+1,r,tr<<1|1);
}
void pushup(int tr)
{
	node[tr].maxn=max(node[tr<<1].maxn,node[tr<<1|1].maxn);
	node[tr].minn=min(node[tr<<1].minn,node[tr<<1|1].minn);
}
void pushdown(int tr)
{
	if(node[tr].cover)
	{
		node[tr<<1].cover+=node[tr].cover;
		node[tr<<1|1].cover+=node[tr].cover;
		node[tr<<1].maxn+=node[tr].cover;
		node[tr<<1|1].maxn+=node[tr].cover;
		node[tr<<1].minn+=node[tr].cover;
		node[tr<<1|1].minn+=node[tr].cover;
		node[tr].cover=0;
	}
}
void update(int L,int R,int val,int l,int r,int tr)
{
	if(L<=l&&r<=R)
	{
		if(node[tr].maxn<p)
		{
			node[tr].maxn+=val;
			node[tr].minn+=val;
			node[tr].cover+=val;
			return;
		}
		if(node[tr].minn>=p)
		{
			node[tr].minn+=(val<<1);
			node[tr].maxn+=(val<<1);
			node[tr].cover+=(val<<1);
			return;
		}
	}
	pushdown(tr);
	int mid=(l+r)>>1;
	if(L<=mid)
		update(L,R,val,l,mid,tr<<1);
	if(R>mid)
		update(L,R,val,mid+1,r,tr<<1|1);
	pushup(tr);
}
void print(int l,int r,int tr)
{
	if(l==r)
	{
		if(l==1)
			printf("%d",node[tr].maxn);
		else
			printf(" %d",node[tr].maxn);
		return;
	}
	int mid=(l+r)>>1;
	pushdown(tr);
	print(l,mid,tr<<1);
	print(mid+1,r,tr<<1|1);
}
int main()
{
//	int n,m,p;
	while(scanf("%d%d%d",&n,&m,&p)!=EOF)
	{
		build(1,n,1);
		while(m--)
		{
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
			update(a,b,c,1,n,1);
		//	print(1,n,1);
		//	printf("\n");
		}
		print(1,n,1);
		printf("\n");
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值