Matrix POJ3685 二分套二分

2022-05-16 05:06:23 字數 1977 閱讀 8523

description

有乙個n階方陣 第i行,j列的值aij =i

2 + 100000 × i + j

2 - 100000 × j + i × j,需要找出這個方陣的第m小值.

input

第一行輸入t代表測試組數.

每個測試用例包含2個數字n,m表示在n階方陣找出第m大值, n(1 ≤ n ≤ 50,000) and m(1 ≤ m≤ n × n). 每兩個測試用例之間可能有空行

output

輸出方陣的第m小值

sample input

12

1 12 1

2 22 3

2 43 1

3 23 8

3 95 1

5 25

5 10

sample output

3

-99993312

100007

-199987

-99993

100019

200013

-399969

400031

-99939

analysis在二分m的大小之後,再次二分統計小於等於m的個數,但是可以有兩個方向

我真的好蠢,調了乙個下午...方向不太好

下面兩個函式是等價的,乙個關於i,乙個關於j

f(i)=i2+(100000+j)×i+j2-100000×j 

f(j)=j2+(i-100000)×j+i2+100000×i)

我們發現第乙個函式的對稱軸小於0,也就是在[1,n]的區間上是單調的,而第二個函式對稱軸是有可能在[1,n]區間裡的,所以要分類討論

我就是寫的第二種...所以有一點...

code

1 #include

2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10

#define rg register ll

11#define rep(i,a,b) for(rg i=a;i<=b;++i)

12#define per(i,a,b) for(rg i=a;i>=b;--i)

13#define ll long long

14#define inf (1<<29)

15#define cal(x,y) (y*y+(x-100000ll)*y+x*x+100000ll*x)

16using

namespace

std;

17ll t;

18ll n,m;

19inline ll read()

2023

while(c>='

0'&&c<='9')

24return x*f;25}

2627

ll check(ll lim)

2842 cnt+=n-ans;43}

44else

4553 cnt+=aof-ans;//

bug!

5455 l=aof+1,r=n,mid,num,ans=aof;

56while(l<=r)

5762 cnt+=ans-aof; 63}

64}65return cnt>=m;66}

6768

intmain()

6981 printf("

%lld\n

",ans);82}

83return0;

84 }

view code

poj 3685 二分套二分

題意 給乙個n n 的矩陣,其中每個元素的大小為 i i 100000 i j j 100000 j i j 現在給n和m,求這個矩陣中第 m 大的元素是什麼。解析 發現上面那個式子是按照,每一列,從小到大遞增的。所以可以先二分設定乙個mi元素,然後按照每一列來二分統計比它小的元素有多少個。如果比它...

poj 3685 Matrix 二分套二分

題意 說的很明確了。思路 很經典的二分套二分,通過觀察表示式我們可以發現當j一定的時候,原表示式的值是跟i相關並且是單調的,所以我們可以二分答案m,然後統計比m小的數有多少個,在統計的時候需要先列舉j,然後再二分i,統計完成後,還需要判斷這個結果是否存在 即是否存在i,j使表示式的值等於m 為此我的...

POJ3685Matrix 二分套二分

傳送門 題目大意 n n的矩陣,a i j i i 100000 i j j 100000 j i j,求矩陣中第k小。n 5 10 4 題解 打個表,發現每一列從上往下單調遞增。在大範圍內二分搜尋,二分第k小為x,然後再二分找矩陣中有多少個比x小的數。include include include...