Conveyor Belt Aizu - 2866(线段树 区间更新&&求区间最大值)

Awesome Conveyor Machine (ACM) is the most important equipment of a factory of Industrial Conveyor Product Corporation (ICPC). ACM has a long conveyor belt to deliver their products from some points to other points. You are a programmer hired to make efficient schedule plan for product delivery.

ACM’s conveyor belt goes through NN points at equal intervals. The conveyor has plates on each of which at most one product can be put. Initially, there are no plates at any points. The conveyor belt moves by exactly one plate length per unit time; after one second, a plate is at position 1 while there are no plates at the other positions. After further 1 seconds, the plate at position 1 is moved to position 2 and a new plate comes at position 1, and so on. Note that the conveyor has the unlimited number of plates: after NN seconds or later, each of the NN positions has exactly one plate.

A delivery task is represented by positions aa and bb; delivery is accomplished by putting a product on a plate on the belt at aa, and retrieving it at bb after b−ab−a seconds (a<ba<b). (Of course, it is necessary that an empty plate exists at the position at the putting time.) In addition, putting and retrieving products must bedone in the following manner:

When putting and retrieving a product, a plate must be located just at the position. That is, products must be put and retrieved at integer seconds.
Putting and retrieving at the same position cannot be done at the same time. On the other hand, putting and retrieving at the different positions can be done at the same time.
If there are several tasks, the time to finish all the tasks may be reduced by changing schedule when each product is put on the belt. Your job is to write a program minimizing the time to complete all the tasks… wait, wait. When have you started misunderstanding that you can know all the tasks initially? New delivery requests are coming moment by moment, like plates on the conveyor! So you should update your optimal schedule per every new request.

A request consists of a start point aa, a goal point bb, and the number pp of products to deliver from aa to bb. Delivery requests will be added QQ times. Your (true) job is to write a program such that for each 1≤i≤Q1≤i≤Q, minimizing the entire time to complete delivery tasks in requests 1 to ii.

Input
The input consists of a single test case formatted as follows.

NN QQ
a1a1 b1b1 p1p1
:
aQaQ bQbQ pQpQ
A first line includes two integers NN and QQ (2≤N≤105,1≤Q≤1052≤N≤105,1≤Q≤105): NN is the number of positions the conveyor belt goes through and QQ is the number of requests will come. The ii-th line of the following QQ lines consists of three integers ai,bi,ai,bi, and pipi (1≤ai<bi≤N,1≤pi≤1091≤ai<bi≤N,1≤pi≤109), which mean that the ii-th request requires pipi products to be delivered from position aiai to position bibi.

Output
In the ii-th line, print the minimum time to complete all the tasks required by requests 11 to ii.

Sample Input 1
5 2
1 4 1
2 3 1
Output for Sample Input 1
4
4
Sample Input 2
5 2
1 4 1
2 3 5
Output for Sample Input 2
4
8
Sample Input 3
5 2
1 3 3
3 5 1
Output for Sample Input 3
5
6
Sample Input 4
10 4
3 5 2
5 7 5
8 9 2
1 7 5
Output for Sample Input 4
6
11
11
16
Regarding the first example, the minimum time to complete only the first request is 4 seconds. All the two requests can be completed within 4 seconds too. See the below figure.
在这里插入图片描述
题干好长。。。
就是有一个长度为n的传送带,一开始这n节都没有东西。每一秒都会在1这个位置产生一个新的板子。板子上可以放东西,但是每次只能放一个。有Q次查询,每一个查询有三个数l,r,p,代表着从位置l到位置r运送p个物品。每一次查询输出的结果是1~i次查询都完成了的最短时间是多少。
一开始真的没有想到会是线段树。。因为一开始想的就是运送东西的整个过程是怎么样的,没有从整体去考虑这个问题。。
首先来说,一开始所有的位置上是没有板子的,所以每个位置产生板子还需要一定的时间。对于第i块板子来说,需要等待i-1秒才行。对于每次任务,l~r有p块板子,那么对于这l到r的所有板子,必须p秒之后才能完事。要查讯1 ~ i次任务最短多长时间完成,就是要查询当前产生的所有板子工作时间最长是多少,这就相当于维护了一个区间最大值问题。在更新的时候需要用到lazy,毕竟是区间更新。
代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxx=1e5+100;
struct node{
	int l;
	int r;
	ll _max;
	ll lazy;
}p[maxx<<2];
int n,m;

inline void pushdown(int cur)
{
	if(p[cur].lazy)
	{
		p[cur<<1]._max+=p[cur].lazy;
		p[cur<<1|1]._max+=p[cur].lazy;
		p[cur<<1].lazy+=p[cur].lazy;
		p[cur<<1|1].lazy+=p[cur].lazy;
		p[cur].lazy=0;
	}
}
inline void pushup(int cur)
{
	p[cur]._max=max(p[cur<<1]._max,p[cur<<1|1]._max);
}
inline void build(int l,int r,int cur)
{
	p[cur].l=l;
	p[cur].r=r;
	p[cur]._max=p[cur].lazy=0;
	if(l==r) 
	{
		p[cur]._max=l-1;
		return ;
	}
	int mid=l+r>>1;
	build(l,mid,cur<<1);
	build(mid+1,r,cur<<1|1);
	pushup(cur);
}
inline void update(int l,int r,ll v,int cur)
{
	int L=p[cur].l;
	int R=p[cur].r;
	if(l<=L&&R<=r)
	{
		p[cur]._max+=v;
		p[cur].lazy+=v;
		return ;
	}
	pushdown(cur);
	int mid=L+R>>1;
	if(r<=mid) update(l,r,v,cur<<1);
	else if(l>mid) update(l,r,v,cur<<1|1);
	else
	{
		update(l,mid,v,cur<<1);
		update(mid+1,r,v,cur<<1|1);
	}
	pushup(cur);
}
inline ll query(int l,int r,int cur)
{
	int L=p[cur].l;
	int R=p[cur].r;
	if(l<=L&&R<=r) return p[cur]._max;
	pushdown(cur);
	int mid=L+R>>1;
	if(r<=mid) return query(l,r,cur<<1);
	else if(l>mid) return query(l,r,cur<<1|1);
	else return max(query(l,mid,cur<<1),query(mid+1,r,cur<<1|1));
	pushup(cur);
}
int main()
{
	int l,r;ll v;
	while(~scanf("%d%d",&n,&m))
	{
		build(1,n,1);
		int R=1;
		while(m--)
		{
			scanf("%d%d%lld",&l,&r,&v);
			R=max(R,r);
			update(l,r,v,1);
			printf("%lld\n",query(1,R,1));
		}
	}
	return 0;
}

努力加油a啊,(o)/~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starlet_kiss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值