Fast Arrangement 线段树

Chinese always have the railway tickets problem because of its’ huge amount of passangers and stations. Now goverment need you to develop a new tickets query system.
One train can just take k passangers. And each passanger can just buy one ticket from station a to station b. Each train cannot take more passangers any time. The one who buy the ticket earlier which can be sold will always get the ticket.
Input
The input contains servel test cases. The first line is the case number. In each test case:
The first line contains just one number k( 1 ≤ k ≤ 1000 ) and Q( 1 ≤ Q ≤ 100000 )
The following lines, each line contains two integers a and b, ( 1 ≤ a < b ≤ 1000000 ), indicate a query.
Huge Input, scanf recommanded.
Output
For each test case, output three lines:
Output the case number in the first line.
If the ith query can be satisfied, output i. i starting from 1. output an blank-space after each number.
Output a blank line after each test case.
Sample Input
1
3 6
1 6
1 6
3 4
1 5
1 2
2 4
Sample Output
Case 1:
1 2 3 5

大体题意是说给你一趟列车能承载的人数和许多排队买票的人,问这些人中哪些可以买到票。首先从题目不难看出考点是线段树的区间更新,利用laze值来简化运算,同时这里的区间更新也是低级版本的,只需要加一就完事了。

说到lazy,确实是线段树区间更新的一个重要工具。lazy思想是说若更新的区间已经完全包含区间s,将s区间标记,暂不向下更新,若下一次的更新或询问需要用的已经标记过的区间的子区间,再将标记过得区间进行向下更新,并且取消对区间s的标记,增加对区间两个左右子树的标记。若一直未询问到,则不向下更新。通过这种方式可以达到节约时间的目的。实际上可以看作一种偷懒的方法,先存起来,不用就不向下展开,只有用的时候才向下展开,是一种节省时间的好办法。

回到这个题,结束对线段树的初始化后,进行的是线段树的调整,如果给定区间内每个节点的最大值还小于能承载人数,说明火车还可以继续上人,就可以进行线段树的修改,继续这样的操作直到输入结束,注意乘客从x上车,y下车,所以乘客在车上的区间为(x,y–),另外一定要注意输出的格式要求,每个数字后都带一个空格,每一组测试用例之间都隔着空的一行,不然会格式错误。

AC代码:

#include<iostream>
#include<stdio.h>
#include<memory.h>
using namespace std;
struct node{
	int l,r,num,lazy;
};
struct node nodes[4000005];
int ans[1000005];
void build(int m,int x,int y)
{
	nodes[m].l=x;
	nodes[m].r=y;
	nodes[m].lazy=0;
	nodes[m].num=0;
	if(x==y) return ;
	int mid=(x+y)/2;
	build(m<<1,x,mid);
	build(m<<1|1,mid+1,y);
}
void pushup(int n)
{
	nodes[n].num=max(nodes[n<<1].num,nodes[n<<1|1].num);
 } 
void pushdown(int m)
{
	if(nodes[m].lazy)
	{
		nodes[m<<1].lazy+=nodes[m].lazy;
		nodes[m<<1|1].lazy+=nodes[m].lazy;
		nodes[m<<1].num+=nodes[m].lazy;
		nodes[m<<1|1].num+=nodes[m].lazy;
		nodes[m].lazy=0;
	}
}
int query(int m,int l,int r)
{
	if(nodes[m].l==l&&nodes[m].r==r)
		return nodes[m].num;
	pushdown(m);
	int mid=(nodes[m].l+nodes[m].r)/2;
	if(l>mid) return query(m<<1|1,l,r);
	else if(r<=mid) return query(m<<1,l,r);
	else return max(query(m<<1,l,mid),query(m<<1|1,mid+1,r)); 
}
void update(int m,int l,int r)
{
	if(nodes[m].l==l&&nodes[m].r==r)
	{
		nodes[m].num+=1;
		nodes[m].lazy+=1;
		return;
	}
	pushdown(m);
	int mid=(nodes[m].l+nodes[m].r)/2;
	if(r<=mid) update(m<<1,l,r);
	else if(l>mid) update(m<<1|1,l,r);
	else{
		update(m<<1,l,mid);
		update(m<<1|1,mid+1,r);
	}
	pushup(m);
}

int main()
{
	int n,ccnt=1;
	cin>>n;
	while(n--)
	{
		int k,q;
		int len=0;
		cin>>k>>q;
		memset(ans,0,sizeof(ans));
		build(1,1,1000000);
		for(int i=0;i<q;i++)
		{
			int x,y;
			cin>>x>>y;
			y--;
			if(query(1,x,y)<k)
			{
				ans[len++]=i+1;
				update(1,x,y);
			}
			
		}
		cout<<"Case "<<ccnt++<<":"<<endl;
		for(int j=0;j<len;j++)
			cout<<ans[j]<<" ";
		cout<<endl;
		cout<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43849505/article/details/87074306
今日推荐