本文摘自部落格,歡迎前往部落格以獲得更好的體驗。
有兩個長度都是 n 的序列 a 和 b ,在 a 和 b 中各取乙個數相加可以得到 n題意很明了,我們只需要將 a 和 b 序列數字的和壓入堆中,並取前 n 個和即可。但是,很明顯,在遇到資料過於 毒瘤 大的情況時,顯然時間複雜度會達到 o(n2n^2
n2個和,求這 n
2n^2
n2個和中最小的 n 個。
輸入格式
第一行乙個正整數 n;
第二行n個整數 a
ia_i
ai , 滿足 ai≤
ai+1
a_i \le a_
ai≤ai
+1 且 ai≤
10
9a_i \le 10^9
ai≤10
9;第三行n個整數 b
ib_i
bi , 滿足 bi≤
bi+1
b_i \le b_
bi≤bi
+1 且 bi≤
10
9b_i \le 10^9
bi≤10
9;1 ≤n
≤100000
1 \le n \le 100000
1≤n≤10
0000
。輸出格式
輸出僅一行,包含n個整數,從小到大輸出這n個最小的和,相鄰數字之間用空格隔開。
2log
n)
o(n^2logn)
o(n2lo
gn) ,顯然超時。
因為兩個序列是遞增的,如若 ai+
bj
a_i + b_j
ai+bj
沒有放入優先佇列,那麼 ai+
bj+1
a_i + b_
ai+bj
+1 呢?
答案是很顯然易見的,並不會放入優先佇列。因為 b 序列滿足 bi≤
bi+1
b_i \le b_
bi≤bi
+1 ,所以 ai+
bj+1
>ai
+b
j>q.
top(
)a_i + b_ > a_i + b_j > q.top()
ai+bj
+1>ai
+bj
>q.
top(
) 。所以 ai+
bj
a_i + b_j
ai+bj
沒有放入優先佇列時,ai+
bj+n
(n
>0)
a_i + b_(n > 0)
ai+bj
+n(
n>0)
也都不會被放入,可以直接 break ,跳轉到 ai+
1+bi
a_ + b_i
ai+1+
bi 繼續列舉。
時間複雜度證明第一行至多掃完它的 1
1\dfrac
11 ,第二行變為 1
2\dfrac
21由此類推,第i行最多 1i(
1≤i≤
n)
\dfrac(1 \le i \le n)
i1(1≤
i≤n)
合在一起,共 11+
12+⋯
+1
n\dfrac+\dfrac+\cdots+\dfrac
11+21
+⋯+
n1尤拉證明過,上面的無窮級數的增長率為 o(l
nn
)o(lnn)
o(lnn)
的因此,總複雜度為 o(n
logn
lnn)
o(n\ logn\ lnn)
o(nlog
nlnn
) ,即 o(n
log2
n)
o(nlog^2n)
o(nlog
2n) 的,證畢
#include#include#includeusing namespace std;
priority_queueq;
int n,a[100005],b[100005],ans[100005];
int main()
else}}
}for(int i = n;i >= 1;i--)
for(int i = 1;i <= n;i++) printf("%d ",ans[i]);
return 0;
}
當 i∗j
>
ni*j>n
i∗j>
n 時,ai+
bj
a_i+b_j
ai+bj
一定不是前 n 小的數。
因為兩個序列均有序,所以如果 x
<=i
x<=i
x<=i
且 y<=j
y<=j
y<=j
那麼 ax+
by
+b ja_x+b_yax +by +bj 。於是至少有 i∗j i*ji∗ j 個數小於等於 ai+ bj a_i+b_j ai+bj 。當 i∗j > ni*j>n i∗j> n 時,一定有多餘 n 個數小於等於 ai+ bj a_i+b_j ai+bj ,所以 ai+ bj a_i+b_j ai+bj 一定不是前 n 小的數。 核心** 待補充 time limit 2000ms memory limit 65536kb 64bit io format lld llu submit status description 我們的小夥伴bingo真的很調皮,他在上課的路上看到樹上有個鳥窩,他就想去把他捅下來,但是鳥窩很高他夠不到,於是他就到處找... 本博文的目錄 1 佇列 2 佇列的例題 3 廣度優先搜尋的例題 1 佇列 佇列是什麼?佇列是一種特殊的線性表,與棧不同,這種線性表只允許在表的前端 我們稱為front或head 進行刪除操作,在表的後端 我們稱作rear或tail 進行插入操作。所以又叫f first i in f first o ... 輸入m行,n列的陣列,給定起點座標x,y和終點座標w,z,求從起點到終點的路徑數。規定可以前後左右移動,但是下一步的值必須比當前值大。示例 輸入 4 5 0 0 1 0 0 0 0 2 0 0 0 0 3 4 0 0 0 7 5 0 0 2 3 2 輸出 2 解法 其實就是很簡單的深度優先搜尋 in...if(i * j >= n) break;
經典優先佇列例題整理
關於佇列(還有廣度優先搜尋的例題)
深度優先搜尋例題