HDU3577Fast Arrangement(线段树+lazy)
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.
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.
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.
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
即判断哪些人能上车;
构建线段树的两种情况:
1,知道范围,且范围不算太大,可以直接构建一个[1,Maxn]的线段树,这样左儿子和右儿子的编号(Lson=now<<1,Rson=now<<1|1)是固定的,不用标记。
2,不提前构造,累加cnt为新节点标号,加一个root;每个点再ch[2]记录左右儿子的编号。
lazy的使用,没啥可说的,注意该update就update。
#include<iostream> #include<string> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int maxn=1000005; int ans[maxn]; struct Node { int l,r,v,lazy; }; struct Tree { Node node[maxn<<2]; void build(int l,int r,int numb) { node[numb].l=l; node[numb].r=r; node[numb].v=0; node[numb].lazy=0; if(l==r) return; int mid=(l+r)>>1; build(l,mid,numb<<1); build(mid+1,r,numb<<1|1); } void PushUp(int numb) { node[numb].v=max(node[numb<<1].v,node[numb<<1|1].v); } void PushDown(int numb) { node[numb<<1].lazy+=node[numb].lazy; node[numb<<1|1].lazy+=node[numb].lazy; node[numb<<1].v+=node[numb].lazy; node[numb<<1|1].v+=node[numb].lazy; node[numb].lazy=0; } void Insert(int l,int r,int numb) { if(node[numb].l>=l&&node[numb].r<=r) { node[numb].v+=1; node[numb].lazy+=1; return; } if(node[numb].lazy) PushDown(numb); int mid=(node[numb].r+node[numb].l)>>1; if(l>mid) Insert(l,r,numb<<1|1); else if(r<=mid) Insert(l,r,numb<<1); else{ Insert(l,mid,numb<<1); Insert(mid+1,r,numb<<1|1); } PushUp(numb); } int query(int l,int r,int numb) { if(node[numb].l>=l&&node[numb].r<=r){ return node[numb].v; } if(node[numb].lazy) PushDown(numb); int mid=(node[numb].r+node[numb].l)>>1; if(l>mid) return query(l,r,numb<<1|1); else if(r<=mid) return query(l,r,numb<<1); else{ return max(query(l,mid,numb<<1),query(mid+1,r,numb<<1|1)); } } }; Tree tree; int main() { int t,Case=1,len=0,k,m,a,b; scanf("%d",&t); while(t--){ len=0; memset(ans,0,sizeof(ans)); scanf("%d%d",&k,&m); tree.build(1,1000000,1); for(int i=0;i<m;i++){ scanf("%d%d",&a,&b); b--; if(tree.query(a,b,1)<k){ ans[len++]=i+1; tree.Insert(a,b,1); } } printf("Case %d:\n",Case++); for(int i=0; i<len; i++) printf("%d ",ans[i]); printf("\n\n"); } return 0; }
It is your time to fight!