hdu3577 Fast Arrangement

Problem Description
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

这一题属于成段更新,需要用到lazy思想,题意是每个人按时间顺序从a站坐到b站,然后每趟车不能超过k个人,输出能够坐车的人。这里要注意从a站坐到b站,区间更新的是[a,b-1].这里先用线段树维护4个变量,l,r,max,cnt.l,r表示区间的左右端点,max表示这一段区间的最大人数,cnt表示这段的增量,也是lazy标志。

关于cnt和max怎么进行更新,这是个难的地方,想了很久。每次如果询问区间比当前整段区间小,那么把这整段区间的增量加到左右子树的增量上,然后再把增量加到左右子树的最大值上,最后这段区间的增量变为0.

<pre name="code" class="cpp">#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
#define maxn 1000005
int num,k,a[100005];

int max(int a,int b){
	return a>b?a:b;
}
struct node{
	int l,r,max,cnt;
}b[4*maxn];

void build(int l,int r,int i)
{
	int mid;
	b[i].l=l;b[i].r=r;b[i].max=b[i].cnt=0;
	if(l==r)return;
	mid=(l+r)/2;
	build(l,mid,i*2);
	build(mid+1,r,i*2+1);
}

int question(int l,int r,int i)
{
	int mid;
	if(b[i].l==l && b[i].r==r){
		return b[i].max;
	}
	if(b[i].cnt){
    	b[i*2].cnt+=b[i].cnt;b[i*2+1].cnt+=b[i].cnt;
    	b[i*2].max+=b[i].cnt;b[i*2+1].max+=b[i].cnt;
    	b[i].cnt=0;
    }
    mid=(b[i].l+b[i].r)/2;
    if(r<=mid)return question(l,r,i*2);
    else if(l>mid)return question(l,r,i*2+1);
    else return max(question(l,mid,i*2),question(mid+1,r,i*2+1));
}

void update(int l,int r,int i)
{
	int mid;
	if(b[i].l==l && b[i].r==r){
		b[i].cnt++;b[i].max++;return;
	}
    if(b[i].cnt){
    	b[i*2].cnt+=b[i].cnt;b[i*2+1].cnt+=b[i].cnt;
    	b[i*2].max+=b[i].cnt;b[i*2+1].max+=b[i].cnt;
    	b[i].cnt=0;
    }
    mid=(b[i].l+b[i].r)/2;
    if(r<=mid)update(l,r,i*2);
    else if(l>mid)update(l,r,i*2+1);
    else {
    	update(l,mid,i*2);
    	update(mid+1,r,i*2+1);
    }
    b[i].max=max(b[i*2].max,b[i*2+1].max);
}

int main()
{
	int m,i,j,T,num1=0,c,d,t;
	scanf("%d",&T);
	while(T--)
	{
		num1++;t=0;
		printf("Case %d:
",num1);
		scanf("%d%d",&k,&m);
		build(1,1000005,1);
		memset(a,0,sizeof(a));
		for(i=1;i<=m;i++){
			scanf("%d%d",&c,&d);
			d--;
			if(question(c,d,1)<k){
				a[++t]=i;
				update(c,d,1);
			}
		}
		for(i=1;i<=t;i++){
			printf("%d ",a[i]);
		}
		printf("

");
	}
	return 0;
}





原文地址:https://www.cnblogs.com/herumw/p/9464783.html