口胡 NOIP2012DAY1 借教室

2021-08-09 12:28:57 字數 2982 閱讀 2949

題目描述

在大學期間,經常需要租借教室。大到院系舉辦活動,小到學習小組自習討論,都需要向學校申請借教室。教室的大小功能不同,借教室人的身份不同,借教室的手續也不一樣。

面對海量租借教室的資訊,我們自然希望程式設計解決這個問題。我們需要處理接下來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,第二行輸出需要修改訂單的申請人編號。

輸入輸出樣例

輸入樣例#1:

4 3

2 5 4 3

2 1 3

3 2 4

4 2 4

輸出樣例#1:

-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 ≤ 10^5;

對於 100%的資料,有1 ≤ n,m ≤ 10^6,0 ≤ ri,dj≤ 10^9,1 ≤ sj≤ tj≤ n。

這道題目顯然可以用線段樹來做,但是如果打的醜可能會超時,但這題的正解其實是貪心,順便說一句,2023年day2的第二題,聰明的質檢員似乎也是貪心,這道題需要用到乙個比較巧妙的字首和思想,這樣說吧,假設你有一列數,然後要進行區間加法,然後詢問你某個數的值是多少?當然是可以用線段樹的,但是有沒有更加簡單的方法,這裡我們可以維護這樣乙個序列,ai,如何維護ai呢,加入要將區間l,r全部加上·乙個s,那麼只需將al加上s,ar+1(r+1為下標)減去s,那麼當我們要詢問i這個元素的值是多少時,只需求出1到i中所有的a的和即為所求,為什麼呢。分類討論一下。

假設現在某個區間l,r加上了乙個s,詢問以i為下標的元素是多少。

①i在區間l,r之前,那麼不會影響到i

②i在區間l,r之中,那麼使i這個元素的值便是原來的值加上s

③i在區間l,r之後,那麼al與ar+1抵消,不受影響。

綜上,得證。

至此,我們就找到了這樣一種方法,可以不用線段樹進行區間修改,同時也可以查詢每乙個元素的值,那麼我們嘗試將這種方法用到這道題目中,首先我們二分乙個答案,然後用上面的方法,判斷是否可行,即可。

是否可以利用這種方法,用在樹狀陣列上,使得樹狀陣列可以區間修改。

const

maxn=1000000+5;

var s,t,d,sum,a:array[0..maxn] of longint;

mid,i,j,l,r,n,m:longint;

function

pd(x:longint):boolean;

var k:longint;

begin

fillchar(sum,sizeof(sum),0);

for i:=1

to x do

begin

inc(sum[s[i]],d[i]);

dec(sum[t[i]+1],d[i]);

end;

k:=0;

for i:=1

to n do

begin

inc(k,sum[i]);

if k>a[i] then

exit(false);

end;

exit(true);

end;

begin

//assign(input,'jzoj3103.in');

//reset(input);

//assign(output,'jzoj3103.out');

//rewrite(output);

readln(n,m);

for i:=1

to n do

read(a[i]);

for i:=1

to m do

read(d[i],s[i],t[i]);

l:=1;

r:=m;

while ldo

begin

mid:=(l+r)div

2; if pd(mid) then

l:=mid+1

else

r:=mid;

end;

if r=m then

writeln(0)

else

begin

writeln(-1);

writeln(r);

end;

//close(input);

//close(output);

end.

thank you!

口胡 NOIP2011DAY1 選擇客棧

乙個長度為 n 的區間,每個位置上有顏色 ci 以及代價 vi,現在問有多少個區間 l,r 滿足 cl cr 且 l i r 使得v i p 我們只考慮每乙個點作為左端點時對答案的貢獻,我們令ne xti 表示在i左邊,離i最近,且vn exti p的那個端點,可以為i本身 那麼i這個端點對答案的貢...

NOIP 2012 Day2T2 借教室題解

題目描述 description 在大學期間,經常需要租借教室。大到院系舉辦活動,小到學習小組自習討論,都需要向學校申請借教室。教室的大小功能不同,借教室人的身份不同,借教室的手續也不一樣。面對海量租借教室的資訊,我們自然希望程式設計解決這個問題。我們需要處理接下來n天的借教室資訊,其中第i天學校有...

NOIP2012 DAY1 T2 國王遊戲

恰逢 h國國慶,國王邀請n位大臣來玩乙個有獎遊戲。首先,他讓每個大臣在左 右手上面分別寫下乙個整數,國王自己也在左 右手上各寫乙個整數。然後,讓這 n 位大臣排成一排,國王站在隊伍的最前面。排好隊後,所有的大臣都會獲得國王獎賞的若干金幣,每位大臣獲得的金幣數分別是 排在該大臣前面的所有人的左手上的數...