nssl1477 賽 對頂堆,貪心

2021-10-09 04:43:36 字數 1802 閱讀 4377

n

nn個物品,有兩個人,每個人有一些喜歡的物品。

選m

mm個物品,至少選擇k

kk個第乙個人喜歡的和k

kk個第二個人喜歡的物品

首先我們必定是選最小的

我們從小到大列舉選擇多少兩個人都喜歡的物品i

ii,然後每人選擇k−x

k-xk−

x只有這個人喜歡的物品,之後我們將剩下的物品丟進乙個資料結構裡,然後求前m−2

∗k+i

m-2*k+i

m−2∗k+

i個最小的物品。

現在我們需要維護乙個資料結構支援每次加入一些物品,然後求前z

zz個最小物品的和。我們發現z

zz是每次增加一的,可以使用對頂堆,保證第乙個堆內只有z

zz個物品然後每次如果更優就交換兩個堆堆頂的數

時間複雜度o(n

log⁡n)

o(n\log n)

o(nlogn)

#include

#include

#include

#include

#define ll long long

using

namespace std;

const ll n=

2e5+10;

priority_queue q1,q2;

ll n,m,k;

ll ans,cnt,cnt1,cnt2,sum1,sum2,sum,sum0;

ll v[n]

,a[n]

,b[n]

,com[n]

,p1[n]

,p2[n]

;int

main()

scanf

("%lld"

,&num)

;for

(ll i=

1;i<=num;i++

)for

(ll i=

1;i<=n;i++

)sort

(com+

1,com+

1+cnt)

;sort

(p1+

1,p1+

1+cnt1)

;sort

(p2+

1,p2+

1+cnt2)

; ans=

1e18

;for

(ll i=

0;i<=

min(cnt,k)

;i++

)while

(cnt2>k-i)

ll ne=m-cnt1-cnt2-i;

if(ne<0)

continue;if

(cnt1+i!=k||cnt2+i!=k)

continue

;while

(!q1.

empty()

&&q2.

size()

while

(!q1.

empty()

&&!q2.

empty()

&&-q1.

top(

)top())

if(q2.

size()

>=ne)

ans=

min(ans,sum0+sum+sum1+sum2);}

if(ans==

1e18

)printf

("-1");

else

printf

("%lld"

,ans)

;}

14 7 新增職工

1 功能分析 用乙個陣列去儲存所有使用者新增的職工,但我們知道,陣列裡只能存放相同型別的元素。多型技術正好滿足的這一需求。例如,建立普通員工時可以這樣寫 worker worker new employee 建立經理時可以這樣寫 worker worker new manager 這樣,這個陣列裡儲...

nssl 1336 膜拜神牛

d es crip tion description descri ptio n 給定長度為n nn的序列a aa和b bb,若滿足ai aj a i geq a j ai aj 且bi b jb i leq b j bi bj 則i,ji,j i,j互相膜拜,求最大的互不膜拜集合 資料範圍 n 1...

nssl1476 聯 線段樹

無限長的01 0101 序列,每次進行乙個操作 區間內賦值為0 00區間內賦值為1 11區間取反 求第乙個0 00的位置 離散化 儲存每個區間的左右端點和他們加一之後的值 後可以用線段樹儲存第乙個0 00和第乙個1 11的位置。然後區間取反時就交換兩個值並且讓laz ylazy lazy 標記同樣取...