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");
}
}