503. 借教室
503. 借教室
題意:
在大學(xué)期間,經(jīng)常需要租借教室。
大到院系舉辦活動,小到學(xué)習(xí)小組自習(xí)討論,都需要向?qū)W校申請借教室。
教室的大小功能不同,借教室人的身份不同,借教室的手續(xù)也不一樣。
面對海量租借教室的信息,我們自然希望編程解決這個問題。
我們需要處理接下來n天的借教室信息,其中第i天學(xué)校有ri個教室可供租借。
共有m份訂單,每份訂單用三個正整數(shù)描述,分別為dj,sj,tj,表示某租借者需要從第sj天到第tj天租借教室(包括第sj天和第tj天),每天需要租借dj個教室。
我們假定,租借者對教室的大小、地點(diǎn)沒有要求。
即對于每份訂單,我們只需要每天提供dj個教室,而它們具體是哪些教室,每天是否是相同的教室則不用考慮。
借教室的原則是先到先得,也就是說我們要按照訂單的先后順序依次為每份訂單分配教室。
如果在分配的過程中遇到一份訂單無法完全滿足,則需要停止教室的分配,通知當(dāng)前申請人修改訂單。
這里的無法滿足指從第sj天到第tj天中有至少一天剩余的教室數(shù)量不足dj個。
現(xiàn)在我們需要知道,是否會有訂單無法完全滿足。
如果有,需要通知哪一個申請人修改訂單。
題解:
題目本質(zhì)就是對一個區(qū)間進(jìn)行修改,看到第幾次修改時會出現(xiàn)負(fù)數(shù)
線段樹肯定可以做
這里說說二分+差分的方法
我們可以發(fā)現(xiàn)教室的數(shù)量隨著租借的情況增長而單調(diào)遞減,所以我們可以二分教室將在第k次租借時不夠
如何驗(yàn)證k是否正確呢?我們求出教室的差分?jǐn)?shù)組,然后對前k次教室進(jìn)行驗(yàn)證,一旦發(fā)現(xiàn)存在負(fù)的,return 0
詳細(xì)看代碼
代碼:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm>using namespace std;typedef long long LL;const int N = 1000010;int n, m; int r[N], d[N], s[N], t[N]; LL b[N];bool check(int k) {for (int i = 1; i <= n; i ++ ) b[i] = r[i];for (int i = 1; i <= k; i ++ ){b[s[i]] -= d[i];b[t[i] + 1] += d[i];}LL res = 0;for (int i = 1; i <= n; i ++ ){res += b[i];if (res < 0) return true;}return false; }int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= n; i ++ ) scanf("%d", &r[i]);for (int i = n; i; i -- ) r[i] -= r[i - 1];for (int i = 1; i <= m; i ++ ) scanf("%d%d%d", &d[i], &s[i], &t[i]);int l = 1, r = m;while (l < r){int mid = l + r >> 1;if (check(mid)) r = mid;else l = mid + 1;}if (check(r)){puts("-1");printf("%d\n", r);}else puts("0");return 0; }總結(jié)