1. 程式人生 > >NOIp2012:借教室

NOIp2012:借教室

的人 提高 題目 輸入輸出格式 空格 接下來 數組 包括 ==

技術分享
題目描述

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

面對海量租借教室的信息,我們自然希望編程解決這個問題。

我們需要處理接下來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,第二行輸出需要修改訂單的申請人編號。 輸入輸出樣例 輸入樣例#14 3 2 5 4 3 2 1 3 3 2 4 4 2 4 輸出樣例#1-1 2 說明 【輸入輸出樣例說明】 第 1 份訂單滿足後,4 天剩余的教室數分別為 0323。第 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。 NOIP 2012 提高組 第二天 第二題
題目

  芒果君:乍一看這題不是線段樹,跟二分有什麽關系O_o…………但是仔細想想,如果申請的人越多就越難滿足條件,很適合用二分做。然後新學了個東西叫差分,很像樹狀數組的思路,把l~r修改的數值做標記(也像lazy),tag[l]+=num,tag[r+1]-=num,調用的時候求前綴和,就是當前位要變更的數值。

  最後我沒考慮到自己求出的答案是“最後一個能滿足的”,不是“第一個不滿足的”,所以答案要加1。

 1 #include<cstdio>
 2
#include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #define maxn 1000010 6 #define ll long long 7 using namespace std; 8 struct jie{ 9 int num,l,r; 10 }J[maxn]; 11 int a[maxn],n,m; 12 ll tag[maxn]; 13 int main() 14 { 15 scanf("%d%d",&n,&m); 16 for(int i=1;i<=n;++i) scanf("%d",&a[i]); 17 for(int i=1;i<=m;++i) scanf("%d%d%d",&J[i].num,&J[i].l,&J[i].r); 18 int l=0,r=m+1; 19 while(r-l>1){ 20 int mid=(l+r)>>1,f=1; 21 for(int i=1;i<=n;++i) tag[i]=0; 22 for(int i=1;i<=mid;++i){ 23 tag[J[i].l]-=J[i].num; 24 tag[J[i].r+1]+=J[i].num; 25 } 26 for(int i=1;i<=n;++i){ 27 tag[i]+=tag[i-1]; 28 if(tag[i]+a[i]<0){ 29 f=0; 30 break; 31 } 32 } 33 if(f) l=mid; 34 else r=mid; 35 } 36 l==m?printf("0"):printf("-1\n%d",l+1); 37 return 0; 38 }

NOIp2012:借教室