1、
nkoj 1887 【noip2012 day2】借教室
時間限制 : 40000 ms 空間限制 : 128000 kb
問題描述
在大學期間,經常需要租借教室。大到院系舉辦活動,小到學習小組自習討論,都需要
向學校申請借教室。教室的大小功能不同,借教室人的身份不同,借教室的手續也不一樣。
面對海量租借教室的資訊,我們自然希望程式設計解決這個問題。
我們需要處理接下來n天的借教室資訊,其中第i天學校有ri個教室可供租借。共有m份
訂單,每份訂單用三個正整數描述,分別為dj, sj, tj,表示某租借者需要從第sj天到第tj天租
借教室(包括第sj天和第tj天),每天需要租借dj個教室。
我們假定,租借者對教室的大小、地點沒有要求。即對於每份訂單,我們只需要每天提
供dj個教室,而它們具體是哪些教室,每天是否是相同的教室則不用考慮。
借教室的原則是先到先得,也就是說我們要按照訂單的先後順序依次為每份訂單分配教
室。如果在分配的過程中遇到乙份訂單無法完全滿足,則需要停止教室的分配,通知當前申
請人修改訂單。這裡的無法滿足指從第sj天到第tj天中有至少一天剩餘的教室數量不足dj個。
現在我們需要知道,是否會有訂單無法完全滿足。如果有,需要通知哪乙個申請人修改
訂單。輸入格式
第一行包含兩個正整數n, m,表示天數和訂單的數量。
第二行包含n個正整數,其中第i個數為ri,表示第i天可用於租借的教室數量。
接下來有m行,每行包含三個正整數dj, sj, tj,表示租借的數量,租借開始、結束分別在第幾天。
每行相鄰的兩個數之間均用乙個空格隔開。天數與訂單均用從1開始的整數編號。
輸出格式
如果所有訂單均可滿足,則輸出只有一行,包含乙個整數 0。否則(訂單無法完全滿足)
輸出兩行,第一行輸出乙個負整數-1,第二行輸出需要修改訂單的申請人編號。
樣例輸入
4 3
2 5 4 3
2 1 3
3 2 4
4 2 4
樣例輸出
-1 2
提示
【輸入輸出樣例說明】
第 1 份訂單滿足後,4 天剩餘的教室數分別為 0,3,2,3。第 2 份訂單要求第 2 天到
第 4 天每天提供 3 個教室,而第 3 天剩餘的教室數為 2,因此無法滿足。分配停止,通知第
2 個申請人修改訂單。
【資料範圍】
對於 10%的資料,有1 ≤ n, m ≤ 10;
對於 30%的資料,有1 ≤ n, m ≤ 1000;
對於 70%的資料,有1 ≤ n, m ≤ 105;
對於 100%的資料,有1 ≤ n, m ≤ 10^6, 0 ≤ ri, dj≤ 10^9, 1 ≤ sj≤ tj≤ n。
**:
#include
#include
using
namespace
std;
const
int need=1000004;
struct yft[need*2];
int c[need],le[need*2],ri[need*2];
int tot=0,z,x,y,anss;
bool mark=false;
void build(int x,int y)
le[s]=tot+1;build(x,(x+y)>>1);
ri[s]=tot+1;build(((x+y)>>1)+1,y);
t[s].v=min(t[le[s]].v,t[ri[s]].v);
}void putdown(int s)
}void nbhb(int s)
if(!(x>t[le[s]].b||yif(!(x>t[ri[s]].b||yint main()
}if(!mark) printf("0");
}
2、
nkoj 1906 【線段樹】火車線路
時間限制 : 10000 ms 空間限制 : 65536 kb
問題描述
某列火車行使在c個城市之間(出發的城市編號為1,結束達到的城市的編號為c),假設該列火車有s個座位,現在有r筆預訂票的業務。現在想對這r筆業務進行處理,看哪些預定能滿足,哪些不能滿足。
一筆預定由o、d、n三個整數組成,表示從起點站o到目標站d需要預定n個座位。一筆預定能滿足是指該筆業務在行程範圍內有能滿足的空座位,否則就不能滿足。一筆業務不能拆分,也就是起點和終點站不能更改,預定的座位數目也不能更改。所有的預定需求按給出先後順序進行處理。
請你編寫程式,看那些預定業務能滿足,那些不能滿足。
輸入格式
第一行為三個整數c、s、r,(1<=c<=60 000, 1<=s<=60 000, 1<=r<=60 000)他們之間用空隔分開。接下來的r行每行為三個整數o、d、n,(1<=o< d<=c, 1<=n<=s),分別表示每一筆預定業務。
輸出格式
對第i筆業務,如果能滿足,則在第i行輸出「t」,否則輸出「n」
樣例輸入
4 6 4
1 4 2
1 3 2
2 4 3
1 2 3
樣例輸出
t t n n
**:
#include
#include
using
namespace
std;
const
int need=60004;
struct fyt[need*2];
int le[need*2],ri[need*2];
int tot=0,tt,x,y,z;
void build(int x,int y)
le[s]=tot+1;build(x,(x+y)>>1);
ri[s]=tot+1;build((x+y)/2+1,y);
t[s].v=min(t[le[s]].v,t[ri[s]].v);
}void putdown(int s)
int getmin(int s)
void str(int s)
str(le[s]),str(ri[s]);
t[s].v=min(t[le[s]].v,t[ri[s]].v);
}int main()
}}
例題 線段樹 lazy
1 1 lazy思想 對整個結點進行的操作,先在結點上做標記,而並非真正執行,直到根據查詢操作的需要分到下層。2 延遲標記 lazy 如果需要對乙個區間中每乙個葉結點進行操作,我們不妨先別忙著操作,而是在所有大區間上做乙個標記,下一次遇到或要用到時,再進行處理 標記傳遞 達到減少操作次數,提高線段樹...
線段樹 lazy標記
每個節點代表區間 唯一根節點,也就是全部區間 葉節點是長度為1的子區間,也就是所代表陣列上的乙個點 const int maxn 1e3 struct segmenttree e 4 maxn 建樹 void build int p,int l,int r int mid l r 2 build p...
線段數簡單描述
線段樹的定義 在資訊學競賽中,經常遇到一些與區間操作有關的題目。比如統計若干個矩形的並集,計算若干區間線段的極值及總和等,這時就會用到 線段樹 這種特殊的資料結構。線段樹是一棵二叉樹,記為t a,b 引數a,b表示區間 a,b 其中b a稱為區間的長度,記為l。線段樹t a,b 也可遞迴定義為 若l...