2013多校第四場 B題

2022-05-13 20:31:47 字數 1438 閱讀 8900

題意:

兩個都含有n個元素的陣列a,b, 求 a[i]+b[j] ( i , j < n ) 的前 m個最小值(m < n)

解題思路:

假定a,b陣列都有序,則我們有下面的結論:

a_1 + b_1 <= a_1 + b_2 <= ... <= a_1 + b_n

a_2 + b_1 <= a_2 + b_2 <= ... <= a_2 + b_n

a_n + b_1 <= a_n + b_2 <= ... <= a_n + b_n

那麼我們就可以得出乙個 n*n 的矩陣.如下形式

a(1,1), a(1,2), ..., a(1,n)

a(2,1), a(2,2), ... ,a(2,n)

a(n,1), a(n,2), ... ,a(n,n)

我們知道,第乙個最小的必定是 a(1,1), 

而且. 從 a(1,1) 位置往下(a(2,1)) 或者 往右(a(1,2)), 其值必定增大.

但是我們又不知道 a(1,2) 與 a(2,1) 之間的關係.

不過, 我們可以想到:

若第k小的數是 a(i,j), 則第 k+1小的數可能是a(i+1,j)與a(i,j+1) 之間的數.

因為還有可能是在 其他的 a( a,b ) 的下或者右中..

又因為 我們只需要取前 m <= n 個數.所以我們使用乙個容器,讓裡頭儲存n個數.

每次從容器中取出乙個最值( a(a,b) ), 則再將其下方( a(a+1,b) ),與右邊( a(a,b+1) ) 的值放入容器中.  

這個容器我們可以選 堆/優先佇列: 

編碼細節:

我們可以預處理把 a(1,1), a(1,2), ...,a(1,n) 這n個數放到堆中, 每次取出最小的a(a,b)時,

則只需要將 a(a+1,b) 加入到堆即可. 因為 a(a,b+1)已經在堆中了. 

這樣.始終維護著堆中包含n個元素. 當輸出滿足m個了就結束即可.

演算法時間複雜度:

優先佇列的 插入與刪除操作都是 log(n). 總共n個元素.

則總體時間複雜度:  nlogn 

view code

#include#include

#include

#include

#include

using

namespace

std;

const

int n = 4e5+10

;int

a[n], b[n], res[n];

intn, m;

struct

node

}node;

priority_queue

q;int

main()

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

}return0;

}

2013第四場多校

多校第四場 6題,打得最好的一場多校。還是cjboy給力。本場比賽我基本上沒什麼貢獻,搞04一搞就是一下午。最後看了09覺得只有狀態壓縮,不知道怎麼優化。1004 圖論,強聯通分量 0 一開始推理的時候思路很清晰,但是接著就腦殘了,沒怎麼細想就直接去套樣例。以為得到了正確的解法,只是需要乙個特判。然...

2013多校第四場 E題 ZZ的研究

題意 有n n 1000 個數 a1,a2,an,ai 10 15,取其中部分組合相乘的到數是乙個完全平方數.求方案總數.其中保證 ai 不包含大於500的質因子.解題思路 解決本題需要有,線性代數基礎.涉及到關於矩陣的初等變換與高斯消元.求解齊次方程.首先考慮,乙個數 x p1 e1 p2 e2 ...

2015 多校第四場 XYZ and Drops

include include include include using namespace std struct node const int maxn 210 vector pair iterator it int d 5 2 int r,c 直接暴力模擬,注意題意 若水珠原來大小為3,恰好某...