小w的矩陣前k大元素(mutiset+優先佇列貪心)
阿新 • • 發佈:2021-01-21
技術標籤:牛客練習
設a陣列為[1,2,3,4,5]
b陣列為[2,2,3]
毫無疑問 ( 1 , 1 ) (1,1) (1,1)最小,次小呢 ? ? ?
我們把 ( 1 , 2 ) (1,2) (1,2)和 ( 2 , 1 ) (2,1) (2,1)入優先佇列,這兩個是可能最小的組合
每次優先佇列彈出來即可。
但是這麼進去會重複
考慮怎麼入隊不會重複
把 ( 1 , 1 ) (1,1) (1,1)入隊
第一次擴充套件成 ( 1 , 2 ) (1,2) (1,2)和 ( 2 , 1 ) (2,1) (2,1)
後續只需要把
(
x
,
y
)
(x,y)
(x,y)擴充套件成
(
x
+
1
,
y
)
(x+1,y)
(x+1,y)即可
那麼 y y y不需要管嗎??
不需要,因為 ( 1 , 2 ) (1,2) (1,2)在隊伍中,如果需要擴充套件 y y y會變成 ( 1 , 3 ) (1,3) (1,3)…
這樣是最優的
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
int n,m,q,a[maxn],b[maxn];
multiset<int>sa,sb;
struct node
{
multiset<int>::iterator pa,pb;
bool operator < (const node &tmp ) const
{
return *pa+*pb>*tmp.pa+*tmp.pb;
}
};
int main()
{
cin >> n >> m >> q;
for(int i=1;i<=n;i++) cin >> a[i];
for(int i=1;i<=m;i++) cin >> b[i];
int x = 1,y = 1;
sa.insert( a[1] ); sb.insert( b[1] );
while( q-- )
{
string w; int k; cin >> w >> k;
if( w[0]=='R' )
{
int ny = min(m,y+k);
for(int i=y+1;i<=ny;i++) sb.insert( b[i] );
y = ny;
}
else if( w[0]=='D' )
{
int nx = min( n,x+k );
for(int i=x+1;i<=nx;i++) sa.insert( a[i] );
x = nx;
}
else
{
priority_queue<node>q;
q.push({sa.begin(),sb.begin()});
for(int i=1;i<=k;i++)
{
node now = q.top(); q.pop();
printf("%d%c",*now.pa+*now.pb," \n"[i==k] );
if( now.pa==sa.begin() )
{
auto w = now.pb; w++;
if( w!=sb.end() ) q.push({now.pa,w});
}
auto w = now.pa; w++;
if( w!=sa.end() ) q.push({w,now.pb});
}
}
}
return 0;
}