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
12sample output1 12 1
2 22 3
2 43 1
3 23 8
3 95 1
5 25
5 10
3analysis在二分m的大小之後,再次二分統計小於等於m的個數,但是可以有兩個方向-99993312
100007
-199987
-99993
100019
200013
-399969
400031
-99939
我真的好蠢,調了乙個下午...方向不太好
下面兩個函式是等價的,乙個關於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 #includeview code2 #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 }
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...