洛谷P1083 [NOIP2012提高组Day2T2]借教室
P1083 借教室
題目描述
在大學期間,經常需要租借教室。大到院系舉辦活動,小到學習小組自習討論,都需要向學校申請借教室。教室的大小功能不同,借教室人的身份不同,借教室的手續也不一樣。
面對海量租借教室的信息,我們自然希望編程解決這個問題。
我們需要處理接下來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。
NOIP 2012 提高組 第二天 第二題
?
【題解】
線段樹裸題,但是看到10^6還是要慫一下。
區間修改題目差分很常見,我們發現可以在On時間內檢查某些方案能否可行
于是我們發現,第一個不滿足的訂單滿足可二分性
二分+差分+前綴和判斷即可
?
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 6 const long long MAXN = 1200000 + 10; 7 const long long MAXM = 1200000 + 10; 8 9 inline void read(long long &x) 10 { 11 x = 0;char ch = getchar(), c = ch; 12 while(ch < '0' || ch > '9')c = ch, ch = getchar(); 13 while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar(); 14 if(c == '-')x = -x; 15 } 16 17 long long n,m,r[MAXN],d[MAXM],s[MAXM],t[MAXM],tmp[MAXN]; 18 19 long long check(long long rank) 20 { 21 for(register long long i = 1;i <= rank;++ i) 22 tmp[s[i]] -= d[i], tmp[t[i] + 1] += d[i]; 23 long long sum = 0; 24 for(register long long i = 1;i <= n;++ i) 25 { 26 sum += tmp[i]; 27 if(sum < 0) 28 { 29 for(register long long i = 1;i <= rank;++ i) 30 tmp[s[i]] += d[i], tmp[t[i] + 1] -= d[i]; 31 return 0; 32 } 33 } 34 for(register long long i = 1;i <= rank;++ i) 35 tmp[s[i]] += d[i], tmp[t[i] + 1] -= d[i]; 36 return 1; 37 } 38 39 int main() 40 { 41 read(n), read(m); 42 for(register long long i = 1;i <= n;++ i) 43 read(r[i]); 44 for(register long long i = 1;i <= n;++ i) 45 tmp[i] = r[i] - r[i - 1]; 46 for(register long long i = 1;i <= m;++ i) 47 read(d[i]), read(s[i]), read(t[i]); 48 long long l = 1, r = m, mid, ans = 0; 49 while(l <= r) 50 { 51 mid = (l + r) >> 1; 52 if(!check(mid))ans = mid, r = mid - 1; 53 else l = mid + 1; 54 } 55 if(!ans) printf("0"); 56 else printf("-1\n%d", ans); 57 return 0; 58 } NOIP2012Day2T2?
?
?
?
?
轉載于:https://www.cnblogs.com/huibixiaoxing/p/7525288.html
總結
以上是生活随笔為你收集整理的洛谷P1083 [NOIP2012提高组Day2T2]借教室的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP-开发环境搭建
- 下一篇: bzoj1089 [SCOI2003]严