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


题意

有一个火车同时最多有k个人,然后有q个人买票,先买先得,问:哪些人能买到。
输入T组样例,对于每组样例:
输入k,q
然后q行,每行两个数 a,b a , b 表示买a到b的票,需要注意的是这个人在b点下车了,座位就空出来了,可以卖给下一个人,即每个区间是 [a,b) [ a , b )


只要这个人能买下这个区间的票,那么这个区间就都加1,表示这些站都多了一个人
当这个人要买的区间中有一站的人数不小于k,则这个人不能买到票,这个区间就不更新

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN = 1000000 + 10;
int N = 1000001;
int tre[MAXN * 4];//线段树本人
int laz[MAXN * 4];//lazy标记
int query_ans;//每一次query的结果
void update(int t, int l, int r, int x, int y)
{
    if (x <= l && r <= y)
    {
        laz[t]++;
        return;
    }
    if (l != r && laz[t] > 0)
    {
        laz[t << 1] += laz[t];
        laz[t << 1 | 1] += laz[t];
        laz[t] = 0;
    }
    int mid = l + r >> 1;
    if (y <= mid)
        update(t << 1, l, mid, x, y);
    else if (x > mid)
        update(t << 1 | 1, mid + 1, r, x, y);
    else
    {
        update(t << 1, l, mid, x, y);
        update(t << 1 | 1, mid + 1, r, x, y);
    }
    tre[t] = max(tre[t << 1] + laz[t << 1], tre[t << 1 | 1] + laz[t << 1 | 1]);
}
void query(int t, int l, int r, int x, int y)
{
    tre[t] += laz[t];
    if (l != r && laz[t] > 0)
    {
        laz[t << 1] += laz[t];
        laz[t << 1 | 1] += laz[t];
    }
    laz[t] = 0;
    if (x <= l && r <= y)
    {
        query_ans = max(query_ans, tre[t]);
        return;
    }
    int mid = l + r >> 1;
    if (y <= mid)
        query(t << 1, l, mid, x, y);
    else if (x > mid)
        query(t << 1 | 1, mid + 1, r, x, y);
    else
    {
        query(t << 1, l, mid, x, y);
        query(t << 1 | 1, mid + 1, r, x, y);
    }
    tre[t] = max(tre[t << 1] + laz[t << 1], tre[t << 1 | 1] + laz[t << 1 | 1]);
}
int main()
{
    int T, k, q;
    scanf("%d", &T);
    for (int CASE = 1; CASE <= T; CASE++)
    {
        memset(laz, 0, sizeof(laz));
        memset(tre, 0, sizeof(tre));
        scanf("%d%d", &k, &q);
        printf("Case %d:\n", CASE);
        for (int i = 1, l, r; i <= q; i++)
        {
            query_ans = 0;
            scanf("%d%d", &l, &r);//实际区间为[l,r)
            query(1, 1, N, l, --r);
            if (query_ans < k)
            {
                printf("%d ", i);
                update(1, 1, N, l, r);//l-r都+1
            }
        }
        printf("\n\n");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值