NOIP2012借教室 (線段樹區間操作)

2021-07-16 10:14:56 字數 2308 閱讀 3698

★★☆   輸入檔案:classrooms.in輸出檔案:classrooms.out簡單對比

時間限制:1 s   記憶體限制:128 mb

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

面對海量租借教室的資訊,我們自然希望程式設計解決這個問題。 

我們需要處理接下來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 ≤ 10^5; 

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

思路:很容易想到線段樹,裸的線段樹區間操作。但是要稍微優化避免超時。其次線段樹太容易寫砸,**中表明以警示。

各種小細節都要注意準確。

#include #include #include #include #define maxn 4123456

#define inf 1000000009

using namespace std;

struct data;

data tree[maxn];

int a[maxn],n,m,pos=0;

bool tmp=1;

void pushdown(int node)

void pushup(int node)

void build(int node,int x,int y)

int mid=(x+y)>>1;

build(node<<1,x,mid);

build((node<<1)+1,mid+1,y);

tree[node].minn=min(tree[node<<1].minn,tree[(node<<1)+1].minn);

tree[node].l=x;tree[node].r=y;tree[node].ada=0;

}void add(int node,int x,int y,int ad)

if(tree[node].minn-tree[node].ada<0)

if(tree[node].l>y || tree[node].r>1;

if(x<=mid)add(node<<1,x,y,ad);

if(y>mid)add((node<<1)+1,x,y,ad); //查詢和修改的區間不要改變!!!

pushup(node);

return;

}int main()

if(pos)printf("-1\n%d\n",pos);

else printf("0\n");

return 0;

}

另一種方法(字首和+二分)

NOIP 2012 借教室 線段樹

水題,但是裸的線段樹複雜度太高,要用帶標記的線段樹,第一次寫這種題,也算來打個備忘。每訪問到乙個結點就先傳一下標記,然後每次修改某個點的標記時再傳一下標記。不過我各種常數優化都試過可怎麼就第20個點還超15ms 難不成是蒟蒻光環專屬特效?include include include using n...

NOIP2012 借教室 (線段樹)

author hany01 date nov 5th.2017 include define for i j k for int i j i end k i i end i define fordown i j k for int i j i end k i i end i define set a...

NOIP2012 借教室 線段樹

題目鏈結 看這道題的時候,題目中的借教室我們可以看作是區間修改,如果有一天不符合的話都不行,第一反應就是線段樹,維護最小值,查詢的時候看是否滿足要求,滿足的話就區間修改。以此類推,直到出現不滿足的情況。但是由於常數問題還是要o2優化才能過,不然只有95分。如下 includeusing namesp...