1. 程式人生 > >HihoCoder1665方塊遊戲([Offer收割]編程練習賽40)(線段樹)

HihoCoder1665方塊遊戲([Offer收割]編程練習賽40)(線段樹)

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)(線段樹)