HDU 5700 區間交(線段樹)

2021-07-12 01:03:31 字數 1421 閱讀 5273

problem description

小a有乙個含有n個非負整數的數列與m個區間。每個區間可以表示為li,ri。

它想選擇其中k個區間, 使得這些區間的交的那些位置所對應的數的和最大。

例如樣例中,選擇[2,5]與[4,5]兩個區間就可以啦。

input

多組測試資料

第一行三個數n,k,m(1≤n≤100000,1≤k≤m≤100000)。

接下來一行n個數ai,表示lyk的數列(0≤ai≤109)。

接下來m行,每行兩個數li,ri,表示每個區間(1≤li≤ri≤n)。

output

一行表示答案

sample input

5 2 3

1 2 3 4 6

4 52 5

1 4sample output

10

題解:先按照左括號進行排序,然後列舉左括號,將右括號位置存入線段樹,

顯然對於當前左括號,只需找到區間從右邊第k個即是當前解。

//#include //#pragma comment(linker, "/stack:1024000000,1024000000")

#include #include #include #include #include #include using namespace std;

#define inf 0x3f3f3f3f

#define ll long long

#define bug cout<<"bug"<>1;

if(mid>=p)update(l,mid,poi<<1,p);

else update(mid+1,r,poi<<1^1,p);

temp[poi]=temp[poi<<1]+temp[poi<<1^1];

}int query(int l, int r, int poi, int k)

int main()

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

scanf("%d%d",&qu[i].l,&qu[i].r);

sort(qu+1,qu+m+1,cmp);

for(int i=1; i<=k-1; ++i)

update(1,n,1,qu[i].r);

long long ans=0;

for(int i=k; i<=m; ++i)

printf("%i64d\n",ans);

}return 0;}/*

5 2 3

1 2 3 4 6

4 52 5

1 4*/

hdu 5700 區間交 線段樹 列舉

傳送門 題意 給定序列a1,a2.an以及m個區間,從m個區間中選出k個區間使k個區間相交的部分和最大。思路 預處理字首和。按照r從小到大l從大到小的順序將所有區間排序,用線段樹維護區間第k小。然後列舉區間的右端點,求出當前第k小左端點,然後計算差值即可。include include includ...

HDU 5700 區間交 離線線段樹

小a有乙個含有n個非負整數的數列與m個區間。每個區間可以表示為li,ri。它想選擇其中k個區間,使得這些區間的交的那些位置所對應的數的和最大。例如樣例中,選擇 2,5 與 4,5 兩個區間就可以啦。多組測試資料 第一行三個數n,k,m 1 n 100000,1 k m 100000 接下來一行n個數...

hdu 5700 區間交(優先佇列)

思路 現將每條線段按左端點公升序排序,依次往堆裡加右端點,若果size k就pop一下。如果size k並且最小的大於當前l則更新一下。因為這樣每個左端點的對應右端點一定是最大的,這裡堆的作用相當於事實求出左端點比當前左端點小的線段中第k大的右端點,而這個肯定是最大的當前左端點對應的區間。inclu...