例題 線段數 lazy

2021-07-14 19:12:42 字數 3492 閱讀 3130

1、

nkoj 1887 【noip2012 day2】借教室

時間限制 : 40000 ms 空間限制 : 128000 kb

問題描述

在大學期間,經常需要租借教室。大到院系舉辦活動,小到學習小組自習討論,都需要

向學校申請借教室。教室的大小功能不同,借教室人的身份不同,借教室的手續也不一樣。

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

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

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

**:

#include

#include

using

namespace

std;

const

int need=1000004;

struct yft[need*2];

int c[need],le[need*2],ri[need*2];

int tot=0,z,x,y,anss;

bool mark=false;

void build(int x,int y)

le[s]=tot+1;build(x,(x+y)>>1);

ri[s]=tot+1;build(((x+y)>>1)+1,y);

t[s].v=min(t[le[s]].v,t[ri[s]].v);

}void putdown(int s)

}void nbhb(int s)

if(!(x>t[le[s]].b||yif(!(x>t[ri[s]].b||yint main()

}if(!mark) printf("0");

}

2、

nkoj 1906 【線段樹】火車線路

時間限制 : 10000 ms 空間限制 : 65536 kb

問題描述

某列火車行使在c個城市之間(出發的城市編號為1,結束達到的城市的編號為c),假設該列火車有s個座位,現在有r筆預訂票的業務。現在想對這r筆業務進行處理,看哪些預定能滿足,哪些不能滿足。

一筆預定由o、d、n三個整數組成,表示從起點站o到目標站d需要預定n個座位。一筆預定能滿足是指該筆業務在行程範圍內有能滿足的空座位,否則就不能滿足。一筆業務不能拆分,也就是起點和終點站不能更改,預定的座位數目也不能更改。所有的預定需求按給出先後順序進行處理。

請你編寫程式,看那些預定業務能滿足,那些不能滿足。

輸入格式

第一行為三個整數c、s、r,(1<=c<=60 000, 1<=s<=60 000, 1<=r<=60 000)他們之間用空隔分開。接下來的r行每行為三個整數o、d、n,(1<=o< d<=c, 1<=n<=s),分別表示每一筆預定業務。

輸出格式

對第i筆業務,如果能滿足,則在第i行輸出「t」,否則輸出「n」

樣例輸入

4 6 4

1 4 2

1 3 2

2 4 3

1 2 3

樣例輸出

t t n n

**:

#include

#include

using

namespace

std;

const

int need=60004;

struct fyt[need*2];

int le[need*2],ri[need*2];

int tot=0,tt,x,y,z;

void build(int x,int y)

le[s]=tot+1;build(x,(x+y)>>1);

ri[s]=tot+1;build((x+y)/2+1,y);

t[s].v=min(t[le[s]].v,t[ri[s]].v);

}void putdown(int s)

int getmin(int s)

void str(int s)

str(le[s]),str(ri[s]);

t[s].v=min(t[le[s]].v,t[ri[s]].v);

}int main()

}}

例題 線段樹 lazy

1 1 lazy思想 對整個結點進行的操作,先在結點上做標記,而並非真正執行,直到根據查詢操作的需要分到下層。2 延遲標記 lazy 如果需要對乙個區間中每乙個葉結點進行操作,我們不妨先別忙著操作,而是在所有大區間上做乙個標記,下一次遇到或要用到時,再進行處理 標記傳遞 達到減少操作次數,提高線段樹...

線段樹 lazy標記

每個節點代表區間 唯一根節點,也就是全部區間 葉節點是長度為1的子區間,也就是所代表陣列上的乙個點 const int maxn 1e3 struct segmenttree e 4 maxn 建樹 void build int p,int l,int r int mid l r 2 build p...

線段數簡單描述

線段樹的定義 在資訊學競賽中,經常遇到一些與區間操作有關的題目。比如統計若干個矩形的並集,計算若干區間線段的極值及總和等,這時就會用到 線段樹 這種特殊的資料結構。線段樹是一棵二叉樹,記為t a,b 引數a,b表示區間 a,b 其中b a稱為區間的長度,記為l。線段樹t a,b 也可遞迴定義為 若l...