HihoCoder1665方塊遊戲([Offer收割]編程練習賽40)(線段樹)
阿新 • • 發佈:2017-12-17
hihocoder 不同的 遊戲 amp tag printf coder std names
時間限制:10000ms
單點時限:1000ms
內存限制:256MB
描述
小Ho在玩一款類似俄羅斯方塊的遊戲。與原版俄羅斯方塊不同的是,落下方塊都是長度不一的橫向長條,並且不能移動也不能變成豎直方向。
XXXXXX <- 長度為6的橫向長條。
第i個長條的最左端的格子坐標是Li,最右端的格子坐標是Ri;長條從很高的位置下落,中途遇到地面或者受到之前長條支撐,就會停在當前高度。
你能計算出每個長條最後停留的高度是多少嗎? 直接停在地面上的長條高度視為1。
例如5個長條依次下落的位置是[10, 15], [7, 12], [12, 19], [1, 4], [1, 7],則每個長條最終停留的位置如下圖所示:
5555555 33333333 222222 4444 111111
輸入
第一行包含一個整數N。
以下N行每行包含兩個整數Li, Ri。
對於30%的數據,1 ≤ N ≤ 1000, 1 ≤ Li ≤ Ri ≤ 1000
對於100%的數據, 1 ≤ N ≤ 100000, 1 ≤ Li ≤ Ri ≤ 100000
輸出
輸出N行,每行包含一個整數,代表第i個長條停留的高度。
- 樣例輸入
-
5 10 15 7 12 12 19 1 4 1 7
- 樣例輸出
-
1 2 3 1 3
#include<iostream> #include<cstdio> #include<cstring> #include<ctime> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; const int maxn=100010; int N,L,R,x,y,z; struct Segment_Tree{ int maxx; int tag; }T[maxn<<2]; void upd(int L,int R,int root){ if(x>R||y<L)return; if(x<=L&&y>=R){ T[root].maxx=z; T[root].tag=z;return;} int mid=(L+R)>>1; if(T[root].tag) T[root<<1].maxx=T[root<<1|1].maxx=T[root<<1].tag=T[root<<1|1].tag=T[root].tag,T[root].tag=0; upd(L,mid,root<<1); upd(mid+1,R,root<<1|1); T[root].maxx=max(T[root<<1].maxx,T[root<<1|1].maxx); } int query(int L,int R,int root){ if(x>R||y<L) return 0; if(x<=L&&y>=R) return T[root].maxx; int mid=(L+R)>>1; if(T[root].tag) T[root<<1].maxx=T[root<<1|1].maxx=T[root<<1].tag=T[root<<1|1].tag=T[root].tag,T[root].tag=0; return max(query(L,mid,root<<1),query(mid+1,R,root<<1|1)); } int main(){ scanf("%d",&N); for(int i=1;i<=N;i++){ scanf("%d%d",&x,&y); int temp=query(1,100000,1); z=temp+1; printf("%d\n",z); upd(1,100000,1); } return 0; }
HihoCoder1665方塊遊戲([Offer收割]編程練習賽40)(線段樹)