armer john最近新建立了乙個農場,並且正在接受奶牛的畜欄分配請求,有些 畜欄會看到農場美妙的風景。
農場由n (1 <= n <= 100,000) 個畜欄組成,編號為1…n,畜欄i可以最多容納c_i只奶牛 (1 <= c_i <= 100,000)。奶牛i希望得到連續的一段畜欄,表示為一段區間 (a_i,b_i) 。 這樣的話奶牛可以在這段牛棚裡面轉悠。(當然,這段畜欄必須要有足夠的空間)
給出m (1 <= m <= 100,000) 個請求,請求出不超過畜欄承載量的情況下,最多可以滿足的請求數。
考慮下面展示的乙個農場:
編號 1 2 3 4 5
容量 | 1 | 3 | 2 | 1 | 3 |
奶牛1 (1, 3)
奶牛2 (2, 5)
奶牛3 (2, 3)
奶牛4 (4, 5)
fj 不能夠同時滿足4頭奶牛的請求,否則3,4號畜欄就會有太多的奶牛。
考慮到奶牛2的請求需要乙個區間包含3號和4號畜欄,我們嘗試這樣一種方案,讓1,3,4號奶牛 的請求都得到滿足,這樣沒有畜欄超出容量的限制,因此,對於上述情況的答案就是3,三頭奶牛 (1,3,4號)的要求可以得到滿足。
首先一看到區間問題,就想到類似線段覆蓋的題目——貪心就出來了
再一看每一頭奶牛都會在乙個區間內遊蕩,就是說每乙個區間內都會加上1,這是區間改變、求和問題——線段樹也出來了
那麼這道題也只是告訴我們每乙個柵欄能有多少牛,並沒有告訴我們乙個區間內的牛數,那麼我們就要進行轉換:
乙個區間最多能存在的牛數就是這乙個區間內柵欄裡最少能存在的牛的個數
這個是很顯然的,那麼這個思路出來後,整道題都好做了
線段覆蓋的貪心很顯然,按右端點排序
然後在建樹的時候求出區間內最小的牛數,這很簡單。
每次放入一頭牛,就查詢這個區間內的最小值是否》=1,也就是查詢是否放牛:
如果》=1,說明可以,ans++,在進行區間change
否則不行
那麼整體思路就是上面這樣
#include
using
namespace std;
#define int long long
int n,m,ans=0;
bool f=1;
struct treetr[
5000000];
struct nodea[
2000000];
int zl[
2000000];
bool
mycmp
(node x,node y)
void
build
(int p,
int l,
int r)
int mid=l+r>>1;
build
(p*2
,l,mid)
;build
(p*2+1
,mid+
1,r)
; tr[p]
.zl=
min(tr[p*2]
.zl,tr[p*2+
1].zl)
;//求最小值
}int
sum(
int p,
int x,
int y)
//向下傳送懶標記
return
min(
sum(p*
2,x,y)
,sum
(p*2+1
,x,y));
//返回
}void
change
(int p,
int x,
int y)
//包含,就減去
if(tr[p]
.tag)
//傳遞
change
(p*2
,x,y)
;change
(p*2+1
,x,y)
; tr[p]
.zl=
min(tr[p*2]
.zl,tr[p*2+
1].zl)
;//重新去最小值
return;}
signed
main()
題解 海亮集訓 dp 子串
題目傳送門 題目描述 有兩個僅包含小寫英文本母的字串 aa 和 bb。現在要從字串 aa 中取出 kk 個互不重疊的非空子串,然後把這 kk 個子串按照其在字串 aa 現的順序依次連線起來得到乙個新的字串,請問有多少種方案可以使得這個新串與字串 bb 相等?注意 子串取出的位置不同也認為是不同的方案...
題解 海亮集訓 倍增 放積木
alice 有 n 塊積木,放置第 i 塊積木會佔據區間 li,ri alice 每次會騰出乙個區間放積木,她希望放的積木盡可能多,對每個詢問區間,你需 要回答 alice 最多可放置的積木數量。注意 積木與積木的放置區間不可重疊,且任意選定的積木放置區間不能超出詢問區間。我們想整解 線段覆蓋,我們...
集訓 Tire 線段樹
訓練題目位址 virtual judge problem a uva 11488 字典樹問題 view source on github problem b hdu 1251 字典樹 view source on github problem c hdu 1247 字典樹 view source o...