poj 3685 Matrix(二分嵌套)
2017-03-02 15:13
288 查看
题目地址:点击打开链接
题意:给你一个n*n矩阵,每一个位置都有一个值,这个值由该点的该点的行列标决定( i^2 + 100000 × i + j^2 - 100000 × j + i × j),问你第m小的元素是多少
思路:
二分答案,然后判断这个答案是在m之前还是之后。那么怎么知道这个二分的值在前在后呢?可以数比他小的数有多少,那怎么数呢?暴力n*n肯定超时,由给出的公式可知j确定时,表达式关于i单调,所以就可以枚举j二分i确定每个j比他小的数由多少个,这样就可以nlogn时间判断,最后复杂度n*logn*logn。
WA:
一开始找到的规律是从右上角开始以对角线形式递增,所以要求第几大,可以通过二分对角线,找到在哪条对角线然后找到行号列号就可以了。。但是不知道为什么wa了...
后来知道了是n到了5*10^4后这个规律就不一定存在了
代码:
WA:
题意:给你一个n*n矩阵,每一个位置都有一个值,这个值由该点的该点的行列标决定( i^2 + 100000 × i + j^2 - 100000 × j + i × j),问你第m小的元素是多少
思路:
二分答案,然后判断这个答案是在m之前还是之后。那么怎么知道这个二分的值在前在后呢?可以数比他小的数有多少,那怎么数呢?暴力n*n肯定超时,由给出的公式可知j确定时,表达式关于i单调,所以就可以枚举j二分i确定每个j比他小的数由多少个,这样就可以nlogn时间判断,最后复杂度n*logn*logn。
WA:
一开始找到的规律是从右上角开始以对角线形式递增,所以要求第几大,可以通过二分对角线,找到在哪条对角线然后找到行号列号就可以了。。但是不知道为什么wa了...
后来知道了是n到了5*10^4后这个规律就不一定存在了
代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; const int C = 1e5; const int maxn = 5e4+5; ll n, m; bool judge(ll x) { ll num = 0; for(ll j = 1; j <= n; j++) { ll l = 1, r = n, ans = 0; while(l <= r) { ll mid = (l+r)/2; ll tmp = mid*mid+C*mid+j*j-C*j+j*mid; if(tmp <= x) l = mid+1, ans = mid; else r = mid-1; } num += ans; if(num >= m) return 1; } return 0; } int main(void) { int t; cin >> t; while(t--) { scanf("%lld%lld", &n, &m); ll ans, l = -C*n, r = n*n+C*n+n*n+n*n; while(l <= r) { ll mid = (l+r)/2; if(judge(mid)) ans = mid, r = mid-1; else l = mid+1; } printf("%lld\n", ans); } return 0; }
WA:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int C = 1e5; const int maxn = 1e5+5; ll a[maxn], n, m; void init() { for(int i = 1; i <= n; i++) a[i] = a[i-1]+i; for(int i = n+1; i <= 2*n-1; i++) a[i] = a[i-1]+n-(i-n); } int main(void) { int t; cin >> t; while(t--) { scanf("%lld%lld", &n, &m); init(); ll tmp = lower_bound(a+1, a+2*n-1, m)-a, row, col; if(m <= (1+n)*n/2) col = n-(a[tmp]-m), row = tmp-(a[tmp]-m); else col = n-(tmp-n)-(a[tmp]-m), row = n-(a[tmp]-m); // cout << tmp <<endl; // cout << row << ' ' << col <<endl; printf("%lld\n", row*row+C*row+col*col-C*col+row*col); } return 0; }
相关文章推荐
- POJ 3685 Matrix 详细题解 (二分嵌套)
- POJ 3685 Matrix 二维的二分
- POJ 3685 Matrix 二分 函数单调性 难度:2
- POJ - 3685 Matrix 二分套二分
- POJ 3685 Matrix 二分求解第K大
- POJ 3685:Matrix 二分
- POJ 3685 - Matrix(二分搜索)
- POJ 3685:Matrix 二分
- poj 3685 Matrix(二分搜索之查找第k大的值)
- POJ - 3685 Matrix(二分/查找第k大值)
- POJ-3685---Matrix (二分)
- POJ - 3685 Matrix 二分
- poj 3685 Matrix 二分里套二分
- POJ_3685_Matrix_(二分,查找第k大的值)
- 二分-poj-3685-Matrix
- 【POJ】3685 - Matrix 二分->查找第K大的值
- POJ 3685 Matrix (二分搜索)
- POJ - 3685 Matrix(二分)
- POJ - 3685 Matrix (二分搜索:查找第k大的值)
- POJ 3685 Matrix(二分套二分)