HDU 3577 Fast Arrangement(线段树功能:区间更新,查询区间的最大覆盖次数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3577


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
 

Author
Louty (Special Thanks Nick Gu)
 

Source
2010 ACM-ICPC Multi-University Training Contest(14)——Host by BJTU


题意:

给出K,和Q,有Q次询问,火车最多同时不能坐超过 K 个乘客,每个乘客都是按次序登车,

若乘客能满足上火车的条件则输出编号,不能就不输出!

PS:

线段树查询区间覆盖次数!

注意:要求的是输入的编号的每个数字后面都有空格,最后一个数字也不例外!

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define lson l , mid , rt << 1
#define rson mid+1 , r , rt << 1 | 1
const int maxn = 1000010;
const int MAXN = 1000000;
int add[maxn<<2];
int sum[maxn<<2];
int ans[100010];
void PushUp(int rt)
{
    sum[rt] = max(sum[rt<<1], sum[rt<<1|1]);
}
void PushDown(int rt)
{
    if(add[rt])
    {
        add[rt<<1] += add[rt];
        add[rt<<1|1] += add[rt];
        sum[rt<<1] += add[rt];
        sum[rt<<1|1] += add[rt];
        add[rt] = 0;
    }
}

void build(int l, int r, int rt)
{
    add[rt] = 0;
    sum[rt] = 0;//开始都是零
    if(l == r)
    {
        return ;
    }
    int mid = (l+r) >> 1;
    build(lson);
    build(rson);
    PushUp(rt);
}

void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l && r<=R)
    {
        add[rt] += c;
        sum[rt] += c;
        return ;
    }
    PushDown(rt);
    int mid = (l + r) >> 1;
    if(L <= mid)
        update(L, R, c, lson);
    if(mid < R)
        update(L, R, c, rson);
    PushUp(rt);
}
int query(int L,int R,int l,int r,int rt)
{
    if(L<=l && r<=R)
    {
        return sum[rt];
    }
    PushDown(rt);
    int mid = (l+r) >> 1;
    int ret = 0;
    if(L <= mid)
        ret = max(ret,query(L, R, lson));
    if(mid < R)
        ret = max(ret,query(L, R, rson));
    return ret;
}
int main()
{
    int t;
    int K, Q;
    int cas = 0;
    scanf("%d",&t);
    while(t--)
    {
        memset(ans,0,sizeof(ans));
        scanf("%d%d",&K,&Q);
        int a, b;
        build(1, MAXN, 1);
        int l = 0;
        for(int i = 1; i <= Q; i++)
        {
            scanf("%d%d",&a,&b);
            b--;
            int tt = query(a, b, 1, MAXN, 1);
            if(tt < K)
            {
                ans[++l] = i;
                update(a, b, 1, 1, MAXN, 1);
            }
        }
        printf("Case %d:\n",++cas);
        //printf("%d",ans[1]);
        for(int i = 1; i <= l; i++)
        {
            printf("%d ",ans[i]);
        }
        printf("\n\n");
    }
    return 0;
}


你可能感兴趣的:(线段树,HDU,区间覆盖)