洛谷P1631 序列合併 二分做法

2021-10-23 21:05:14 字數 1229 閱讀 2343

洛谷p1631

之前也寫的二分一直過不了,以為不行,然後看了這篇laorui的題解後發現只要把陣列開大一點就能過。

做了一點優化之後決定寫一篇題解 因為他的**過於清奇

思路就是二分去找數,只要這裡面兩兩求和的對滿足有n個就是true,否則就是false,因為單調增的原因只要找n個數所以judge只需要n的複雜度最後複雜度就是nlogm

但是要考慮的是可能二分judge裡的退出條件設定小了,可能提前退出了,前面選中的對可能有重複,小的對可能在後面就選不到小的了。

所以得擴大退出條件,大膽假設只需要二倍的n就行了,雖然不知道怎麼證明。hoho不過總之是過了。

以及要注意二分之後的目標陣列不一定是答案,因為最後在judge裡跑的不一定是正確的數。

還有就是二分的初始值,左端點是等於a[0]+b[0],右端點只需要等於a[d]+b[d]就行了,d=ceil(sqrt(n))-1,比這個數大的時候是顯然會有超過n對的。

主要看**

#include

using

namespace std;

const

int max_n=

2e5+5;

int a[max_n]

,b[max_n]

;int ans[max_n]

;int n,cnt,lim;

bool

judge

(int max1)

else}}

if(cnt>=n)

return

true

;else

return

false;}

intmain()

for(j=

0;j)int d=

ceil

(sqrt

(n))-1

;//求右端點的位置

int l=a[0]

+b[0

],r=a[d]

+b[d]

,mid;

int ans1=0;

while

(l<=r)

else

}//結束之後要拿ans1再跑一遍,因為最後執行的mid不一定是滿足的

judge

(ans1)

;sort

(ans,ans+cnt)

;//排序之後輸出前n個

for(i=

0;i)return0;

}

洛谷 P1631 序列合併

題目描述 有兩個長度都是n的序列a和b,在a和b中各取乙個數相加可以得到n 2個和,求這n 2個和中最小的n個。輸入輸出格式 輸入格式 第一行乙個正整數n 第二行n個整數ai,滿足ai ai 1且ai 10 9 第三行n個整數bi,滿足bi bi 1且bi 10 9.資料規模 對於50 的資料中,滿...

洛谷 P1631 序列合併

有兩個長度都是n的序列a和b,在a和b中各取乙個數相加可以得到n 2個和,求這n 2個和中最小的n個。第一行乙個正整數n 第二行n個整數ai,滿足ai ai 1且ai 10 9 第三行n個整數bi,滿足bi bi 1且bi 10 9.輸出僅一行,包含n個整數,從小到大輸出這n個最小的和,相鄰數字之間...

洛谷P1631 序列合併

序列合併 問題描述 有兩個長度都是n的序列a和b,在a和b中各取乙個數相加可以得到n 2個和,求這n 2個和中最小的n個 n 100000 分析 a i 與b j 相加後,下面相加的一定是a i 1 b j 或a i b j 1 一開始我們把b 1 與a中所有元素相加放入乙個小根堆裡,輸出min,然...