• 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;
    }




    
    
  • 相关阅读:
    一些简单的问题
    WebRTC的 windows 7 环境搭建
    HTML常用标签
    参考C#编程规范
    C#窗体调用(转载)
    java中的小知识(不断更行中。。。。。)
    CF1483E Vabank 题解
    CF755G PolandBall and Many Other Balls 题解
    CF1483D Useful Edges 题解
    CF1368F Lamps on a Circle 题解
  • 原文地址:https://www.cnblogs.com/herumw/p/9464783.html
Copyright © 2020-2023  润新知