區間覆蓋問題小結

2021-08-21 17:25:23 字數 4370 閱讀 9258

好像接觸過不少區間覆蓋類的問題了,寫個部落格小結一下。

1,求最大覆蓋次數

問題描述:相當於給你一些區間,每次給這些區間內的點值都加一(初始都為0),然後問最大的值是多少。(也就是單點的最大覆蓋次數)

解決思路:顯然樹狀陣列可以很好地解決,複雜度nlogn,顯得有些大材小用了。現在有乙個好寫複雜度還低一點的辦法:把所有區間的左端點標為1,右端點標為-1,再從頭到尾遍歷一遍加上當前點的值,維護ans為最大值即可。

tips:為了防止乙個區間的右端點和另乙個的左端點重合導致答案錯誤,採取r++操作,可以證明不會影響結果。

**實現:

#include#include#include#include#include#include#include#include#include#include#include#include#include#define fast ios::sync_with_stdio(false)

#define lowbit(x) x&(-x)

typedef long long ll;

const int inf = 0x3f3f3f3f;

const int mod = (int)1e9 + 7;

const int maxn = (int)1e5 + 5;

using namespace std;

int a[maxn];

int main()

int t = 0, ans = -inf;

for(int i = 1; i <= n; i++)

cout << ans << endl;

return 0;

}

2,求最多不相交區間

問題描述:經典例題:乙個人要參加一些會議,給你這些會議的開始和結束時間,問你他最多能參加多少會議。

解題思路:貪心的思想做。貪心策略:哪個越早結束就先參加哪個。結構體排序,按結束時間排,再貪心遍歷求解即可。

**實現:

#include#include#include#include#include#include#include#include#include#include#include#include#include#define fast ios::sync_with_stdio(false)

#define lowbit(x) x&(-x)

typedef long long ll;

const int inf = 0x3f3f3f3f;

const int mod = (int)1e9 + 7;

const int maxn = (int)1e5 + 5;

using namespace std;

struct hia;

bool cmp(hia x, hia y)

hia z[maxn];

int main()

printf("%d\n", sum);

return 0;

}

例題:略略略

3,求被覆蓋i次的點的個數

問題描述:給你n個區間,分別求出被覆蓋1-n次的點的個數

解題思路:把端點從小到大排個序,左端點標個1,右端點標個-1(實際上是右端點的後面一位,避免左端點和另乙個的右端點重合情況的干擾),從左到右掃一遍,這樣就能很方便地求出不同區間覆蓋次數的值。

如圖,給兩個區間[1,7], [5, 12],用now記錄當前我們加的字首和,我們在遍歷到5的時候,有cnt[1] += (5-3),(now ==1)遍歷到8的時候,cnt[2] += (8 - 5),(now == 2)(其實這裡是區間[5,7]的貢獻,這也能解釋為什麼在標記的時候標記右端點的後一位),再遍歷到13,cnt[1] += (13 - 8),(now == 1)。這樣就能很好的完成記錄。

**:(用map顯然更方便一點)

#include#include#include#include#include#include#include#include#include#include#include#include#include#define fast ios::sync_with_stdio(false)

#define lowbit(x) x&(-x)

typedef long long ll;

const int inf = 0x3f3f3f3f;

const int mod = (int)1e9 + 7;

const int maxn = (int)2e5 + 5;

using namespace std;

mapm;

ll cnt[maxn];

int main()

int now = 0;

ll t = 0;

map::iterator it;

for(it = m.begin(); it != m.end(); it++)

for(int i = 1; i < n; i++)

printf("%lld ", cnt[i]);

printf("%lld\n", cnt[n]);

return 0;

}

例題:cross fire!!!

4,求最少的能覆蓋區間的區間數

大意:給乙個區間[l, r],再給一些[l[i], r[i]],求用這些區間覆蓋[l, r]的最少數目

解決思路:貪心解決。把這些區間以左端點進行排序,先選擇第乙個區間,之後的貪心策略就是選擇在可選範圍內的,選擇右端點最大的區間。

**:

#include#include#include#include#include#include#include#include#include#include#include#include#include#define fast ios::sync_with_stdio(false)

#define lowbit(x) x&(-x)

typedef long long ll;

const int inf = 0x3f3f3f3f;

const int mod = (int)1e9 + 7;

const int maxn = 25005;

using namespace std;

struct hia a[maxn];

bool cmp(hia x, hia y)

int main()

sort(a, a + n, cmp);

int ans = 0, i = 0, temp = 0;

while(temp < t && i < n)

temp = top;

} if(temp < t) puts("-1");

else printf("%d\n", ans);

return 0;

}

(此**可 ac   poj2376)

5,求一段區間覆蓋了多少個其他的區間

大意:給你一些區間,有一些詢問,每次詢問給乙個區間,輸出這個區間覆蓋了多少區間

解題思路:用二維字首和來做。乙個區間用a[l, r]來表示。詢問的時候就相當於求[l, l] 到 [r, r]這個矩形中的元素數目

即sum[r][r] - sum[r][l-1] - sum[l-1][r] + sum[l-1][l-1]

#include#include#include#include#include#include#include#include#include#include#include#include#include#define fi first

#define se second

#define pb push_back

#define lowbit(x) x&(-x)

#define pii pair#define all(x) x.begin(), x.end()

#define fast ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)

typedef long long ll;

const int inf = 0x3f3f3f3f;

const int mod = (int)1e9 + 7;

const int maxn = (int)150000 + 5;

using namespace std;

int sum[505][505];

int main()

for(int i = 1; i <= n; i++)

} while(q--)

return 0;

}

例題:d - atcoder express

區間貪心問題小結(區間選點,區間覆蓋,區間選取)

貪心演算法 思想 什麼是貪心演算法,什麼算得上是貪心 貪心演算法 又稱貪婪演算法 是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,只做出在某種意義上的區域性最優解。貪心演算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無後效性...

區間覆蓋問題

time limit 1000ms memory limit 65536k 用i來表示x座標軸上座標為 i 1,i 的長度為1的區間,並給出n 1 m 200 個不同的整數,表示n個這樣的區間。現在要求畫m條線段覆蓋住所有的區間,條件是 每條線段可以任意長,但是要求所畫線段的長度之和最小,並且線段的...

區間覆蓋問題

time limit 1000ms memory limit 65536k 用i來表示x座標軸上座標為 i 1,i 的長度為1的區間,並給出n 1 m 200 個不同的整數,表示n個這樣的區間。現在要求畫m條線段覆蓋住所有的區間,條件是 每條線段可以任意長,但是要求所畫線段的長度之和最小,並且線段的...