247. 售票系統
【問題描述】
某次列車途經C個城市,城市編號依次為1到C,列車上共有S個座位,鐵路局規定售出的車票只能是坐票, 即車上所有的旅客都有座。售票系統是由電腦執行的,每一個售票申請包含三個參數,分別用O、D、N表示,O為起始站,D為目的地站,N為車票張數。售票 系統對該售票申請作出受理或不受理的決定,只有在從O到D的區段內列車上都有N個或N個以上的空座位時該售票申請才被受理。請你寫一個程式,實現這個自動 售票系統。
【輸入格式】
第一行包含三個用空格隔開的整數C、S和R,其中1≤C≤60000, l≤S≤60000,1≤R≤60000。C為城市個數,S為列車上的座位元,R為所有售票申請總數。接下來的R行每行為一個售票申請,用三個由空格隔開的整數O,D和N表示,O為起始站,D 為目的地站,N為車票站數,其中1≤D≤C,1≤O≤C,所有的售票申請按申請的時間從早到晚給出。
【輸出格式】
輸出共有R行,每行輸出一個“YES”或“NO”,表示當前的售票申請被受理或不被受理。
【輸入輸出範例】
輸入:
4 6 4
1 4 2
1 3 2
2 4 3
1 2 3
輸出:
YES
YES
NO
NO
線段樹 lazy 標記。。關鍵還是處理好標記。什麼時候下放。什麼時候回放。在更新的時候,更新一個區間的值時,那麼這麼區間的總個數已經加過。所以下次操作只需要增加這個區間的子樹就可以了。同時還要更新父親節點。
下面是AC代碼:
#include<cstdio>#include<algorithm>using namespace std;const int maxn = 60000+10;struct node{ int l,r; int tot; int lazy;}T[maxn<<2];int s;void build(int id,int l,int r){ T[id].l=l; T[id].r=r; T[id].tot=0;T[id].lazy=0; if(l==r) return; int m=(l+r)>>1; build(id<<1,l,m); build(id<<1|1,m+1,r);}void update(int id,int l,int r,int n){ if(T[id].l==l&&T[id].r==r){ T[id].lazy+=n; T[id].tot+=n; return ; } if(T[id].lazy!=0){ T[id<<1].tot+=T[id].lazy; T[id<<1|1].tot+=T[id].lazy; T[id<<1].lazy+=T[id].lazy; T[id<<1|1].lazy+=T[id].lazy; T[id].lazy=0; } int m=(T[id].l+T[id].r)>>1; if(m>=r) update(id<<1,l,r,n); else if( l>m) update(id<<1|1,l,r,n); else{ update(id<<1,l,m,n); update(id<<1|1,m+1,r,n); } T[id].tot=max(T[id<<1].tot,T[id<<1|1].tot);}int query(int id,int l,int r){ if(T[id].l==l&&T[id].r==r) return T[id].tot; if(T[id].lazy!=0){ T[id<<1].tot+=T[id].lazy; T[id<<1|1].tot+=T[id].lazy; T[id<<1].lazy+=T[id].lazy; T[id<<1|1].lazy+=T[id].lazy; T[id].lazy=0; } int m=(T[id].l+T[id].r)>>1; if(m>=r) return query(id<<1,l,r); else if( l>m) return query(id<<1|1,l,r); else{ return max(query(id<<1,l,m),query(id<<1|1,m+1,r)); }}int main(){ freopen("railway.in","r",stdin); freopen("railway.out","w",stdout); int c,r; int left,right,n; scanf("%d%d%d",&c,&s,&r); build(1,1,c+1); for(int i=0;i<r;i++){ scanf("%d%d%d",&left,&right,&n); right--; int sum=query(1,left,right); if(s-sum>=n) update(1,left,right,n), puts("YES"); else puts("NO"); } return 0;}