POJ3658Matrix( 双重二分+负数+死循环)
POJ 3658 Matrix
双重二分,wa了一下午,实在不太明白为啥一写二分就会进入死循环.
INF要设的大一些,本题设0x3f3f3f3f会wa.
本题有负数, 二分时(l+r)/2与(l+r)>>1的结果有所不同;
如 l=0,r=-1,则 (l+r)/2=0,而(l+r)>>1=-1,而我们需要的正确答案是-1,所以第一种二分必须写成(l+r)>>1
以下两种二分可过:
(l+r)>>1
/* * FillName: 二重二分 * Created: 2016年04月02日 14时48分41秒 星期六 * Author: Akrusher * */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <string> #include <vector> #include <deque> #include <list> #include <set> #include <map> #include <stack> #include <queue> #include <numeric> #include <iomanip> #include <bitset> #include <sstream> #include <fstream> using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define in(n) scanf("%d",&(n)) #define in2(x1,x2) scanf("%d%d",&(x1),&(x2)) #define inll(n) scanf("%I64d",&(n)) #define inll2(x1,x2) scanf("%I64d%I64d",&(x1),&(x2)) #define inlld(n) scanf("%lld",&(n)) #define inlld2(x1,x2) scanf("%lld%lld",&(x1),&(x2)) #define inf(n) scanf("%f",&(n)) #define inf2(x1,x2) scanf("%f%f",&(x1),&(x2)) #define inlf(n) scanf("%lf",&(n)) #define inlf2(x1,x2) scanf("%lf%lf",&(x1),&(x2)) #define inc(str) scanf("%c",&(str)) #define ins(str) scanf("%s",(str)) #define out(x) printf("%d\n",(x)) #define out2(x1,x2) printf("%d %d\n",(x1),(x2)) #define outf(x) printf("%f\n",(x)) #define outlf(x) printf("%lf\n",(x)) #define outlf2(x1,x2) printf("%lf %lf\n",(x1),(x2)); #define outll(x) printf("%I64d\n",(x)) #define outlld(x) printf("%lld\n",(x)) #define outc(str) printf("%c\n",(str)) #define pb push_back #define mp make_pair #define fi first #define se second #define SZ(x) ((int)(x).size()) #define mem(X,Y) memset(X,Y,sizeof(X)); typedef vector<int> vec; typedef long long ll; typedef pair<int,int> P; const int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1}; const ll INF=1e12; //INF要设的大一些,本题设0x3f3f3f3f会wa const ll mod=1e9+7; ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} const bool AC=true;int t,n; ll m; ll cal(ll i,ll j){ //返回矩阵a[i][j]的值,数组会超内存return i*i+j*j+100000*i-100000*j+i*j; //int可能会爆 } ll C(ll x){ //此处改为int会莫名奇妙的wa,返回值也得是llint l,r,mid2;ll cnt; //此处一定要是llcnt=0;rep(j,1,n+1){l=1,r=n+1;while(r>l){mid2=(r+l)/2;if(cal(mid2,j)>=x) r=mid2; //本题要求的是第m大的值else l=mid2+1;}cnt+=r-1;}return cnt; } int main() {ll ub,lb,mid;in(t);while(t--){in(n);inlld(m);lb=-INF,ub=INF; //INF要设的大一些while(ub>lb){mid=(ub+lb)>>1; //有负数,不能写成(l+r)/2if(C(mid)>=m) ub=mid; //类似中位数的那个题else lb=mid+1;}outlld(ub-1);//最后要减1}return 0; }
下面这种也可以过
(l+r)/2
/* * FillName: 二重二分 * Created: 2016年04月02日 14时48分41秒 星期六 * Author: Akrusher * */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <string> #include <vector> #include <deque> #include <list> #include <set> #include <map> #include <stack> #include <queue> #include <numeric> #include <iomanip> #include <bitset> #include <sstream> #include <fstream> using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define in(n) scanf("%d",&(n)) #define in2(x1,x2) scanf("%d%d",&(x1),&(x2)) #define inll(n) scanf("%I64d",&(n)) #define inll2(x1,x2) scanf("%I64d%I64d",&(x1),&(x2)) #define inlld(n) scanf("%lld",&(n)) #define inlld2(x1,x2) scanf("%lld%lld",&(x1),&(x2)) #define inf(n) scanf("%f",&(n)) #define inf2(x1,x2) scanf("%f%f",&(x1),&(x2)) #define inlf(n) scanf("%lf",&(n)) #define inlf2(x1,x2) scanf("%lf%lf",&(x1),&(x2)) #define inc(str) scanf("%c",&(str)) #define ins(str) scanf("%s",(str)) #define out(x) printf("%d\n",(x)) #define out2(x1,x2) printf("%d %d\n",(x1),(x2)) #define outf(x) printf("%f\n",(x)) #define outlf(x) printf("%lf\n",(x)) #define outlf2(x1,x2) printf("%lf %lf\n",(x1),(x2)); #define outll(x) printf("%I64d\n",(x)) #define outlld(x) printf("%lld\n",(x)) #define outc(str) printf("%c\n",(str)) #define pb push_back #define mp make_pair #define fi first #define se second #define SZ(x) ((int)(x).size()) #define mem(X,Y) memset(X,Y,sizeof(X)); typedef vector<int> vec; typedef long long ll; typedef pair<int,int> P; const int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1}; const ll INF=1e12; //INF要设的大一些,本题设0x3f3f3f3f会wa const ll mod=1e9+7; ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} const bool AC=true;int t,n; ll m; ll cal(ll i,ll j){ //返回矩阵a[i][j]的值,数组会超内存return i*i+j*j+100000*i-100000*j+i*j; //int可能会爆 } ll C(ll x){ //此处改为int会莫名奇妙的wa,返回值也得是llint l,r,mid2;ll cnt; //此处一定要是llcnt=0;rep(j,1,n+1){l=1,r=n+1;while(r>l){mid2=(r+l)/2;if(cal(mid2,j)>=x) r=mid2; //本题要求的是第m大的值else l=mid2+1;}cnt+=r-1;}return cnt; } int main() {ll ub,lb,mid;in(t);while(t--){in(n);inlld(m);lb=-INF,ub=INF; //INF要设的大一些while(ub-lb>1){mid=(ub+lb)/2; if(C(mid)>=m) ub=mid; else lb=mid;}outlld(lb);}return 0; }
下面这种做标记的二分也挺有意思
/* * FillName: 二重二分 * Created: 2016年04月02日 14时48分41秒 星期六 * Author: Akrusher * */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <string> #include <vector> #include <deque> #include <list> #include <set> #include <map> #include <stack> #include <queue> #include <numeric> #include <iomanip> #include <bitset> #include <sstream> #include <fstream> using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define in(n) scanf("%d",&(n)) #define in2(x1,x2) scanf("%d%d",&(x1),&(x2)) #define inll(n) scanf("%I64d",&(n)) #define inll2(x1,x2) scanf("%I64d%I64d",&(x1),&(x2)) #define inlld(n) scanf("%lld",&(n)) #define inlld2(x1,x2) scanf("%lld%lld",&(x1),&(x2)) #define inf(n) scanf("%f",&(n)) #define inf2(x1,x2) scanf("%f%f",&(x1),&(x2)) #define inlf(n) scanf("%lf",&(n)) #define inlf2(x1,x2) scanf("%lf%lf",&(x1),&(x2)) #define inc(str) scanf("%c",&(str)) #define ins(str) scanf("%s",(str)) #define out(x) printf("%d\n",(x)) #define out2(x1,x2) printf("%d %d\n",(x1),(x2)) #define outf(x) printf("%f\n",(x)) #define outlf(x) printf("%lf\n",(x)) #define outlf2(x1,x2) printf("%lf %lf\n",(x1),(x2)); #define outll(x) printf("%I64d\n",(x)) #define outlld(x) printf("%lld\n",(x)) #define outc(str) printf("%c\n",(str)) #define pb push_back #define mp make_pair #define fi first #define se second #define SZ(x) ((int)(x).size()) #define mem(X,Y) memset(X,Y,sizeof(X)); typedef vector<int> vec; typedef long long ll; typedef pair<int,int> P; const int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1}; const ll INF=1e12; //INF要设的大一些,本题设0x3f3f3f3f会wa const ll mod=1e9+7; ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} const bool AC=true;int t,n; ll m; ll cal(ll i,ll j){ //返回矩阵a[i][j]的值,数组会超内存return i*i+j*j+100000*i-100000*j+i*j; //int可能会爆 } ll C(ll x){ //此处改为int会莫名奇妙的wa,返回值也得是ll ll l,r,mid2;ll cnt,res; //此处一定要是llcnt=0;rep(j,1,n+1){l=1,r=n;res=0;while(r>=l){mid2=(r+l)>>1;//起标记的作用if(cal(mid2,j)<=x) {res=mid2;l=mid2+1;}else r=mid2-1;}cnt+=res;}return cnt; } int main() {ll ub,lb,mid,ans;in(t);while(t--){in(n);inll(m);lb=-INF,ub=INF; //INF要设的大一些ans=0;while(ub>=lb){mid=(ub+lb)>>1; //有负数,不能写成(l+r)/2if(C(mid)>=m) {ans=mid;ub=mid-1; //带标记的二分 }else lb=mid+1;}outll(ans);}return 0; }
转载于:https://www.cnblogs.com/akrusher/p/5347855.html
POJ3658Matrix( 双重二分+负数+死循环)相关推荐
- LeetCode-数据结构
文章目录 应做未做 未弄懂 经典题+易错题 一.长见识的方法 二.杂七杂八积累 三.面试常考题目索引 java刷题常用 树 数组 摩尔投票算法 堆 数据流的中位数 排序 四.基础知识总结 4.x 数组 ...
- 经典基础算法的一些精髓和注意点总结
一.搜索遍历算法 0.搜索概论 搜索,某个维度(角度)上分为两种,分别是遍历逻辑结构和遍历状态空间结构,二者都是一张图,而一个是题目给定的,一个是由题目给定所确定的 所谓状态空间,就是这个问题的询问, ...
- NKU 专题一 题解
A - Flip Game 总的情况数只有2^16次方种,显然直接bfs就可以了 1 #include<iostream> 2 #include<queue> 3 #inclu ...
- HDU 1069 Monkey and Banana
传送门 #include<iostream> #include<algorithm> #include<map> #include<set> #incl ...
- AcWing 1010 拦截导弹
题目描述: 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统. 但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度. 某天,雷达捕捉到敌国 ...
- 【二分查找万能模板,告别死循环、告别越界】Leecode 34. 在排序数组中查找元素的第一个和最后一个位置
题目链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/ 题解汇总: ...
- leetcode1351. 统计有序矩阵中的负数(二分查找)
给你一个 m * n 的矩阵 grid,矩阵中的元素无论是按行还是按列,都以非递增顺序排列. 请你统计并返回 grid 中 负数 的数目. 示例 1: 输入:grid = [[4,3,2,-1],[3 ...
- jzoj3463-军训【双重嵌套二分,随机数据水法】
正题 大意 每个人有两个值gigig_i和hihih_i,要求将序列分解成连续的几个序列.要求每个序列最大的hihih_i的和小于Limt的情况下每个序列gigig_i的和的最大值最小. 解题思路 我 ...
- 1.1.4 分支, if, if else, if elseif else, switch,循环,for,break,continue,双重for,while, do while
&&&&&总结&&&&& 1, 分支结构 if分支结构, if else分支结构, if elseif else分支结构 ...
- #2020寒假集训#二分入门(Binary Search)代码笔记
二分查找--Binary Search 原理就类似于下图啦(网上看到哒,忽略这个代价) 二分的时间复杂度一般是 O(logN) 的,超开心了有木有٩(๑>◡<๑)۶ 最简单来说,它可以分为 ...
最新文章
- python主要就业方向-【数据说话】当下的Python就业前景如何
- linux下直接使用base64就可转换图片为二进制
- Ask Me Anything #1 我是新晋CNCF TOC张磊,你有什么想问我的?
- 2021年中国云计算软件市场趋势报告、技术动态创新及2027年市场预测
- micro-mvc与主流mvc整合说明
- oracle 误删除数据,回退表数据
- 设置tomcat内存
- 服务器里怎么设置微信多开,企业微信多开的4种方法
- python做项目看板_基于pyecharts搭建BI看板
- 5 steps to autotools GNU diction
- ubuntu桌面图标不显示问题
- 计算机图像变为红色是什么故障,电脑显示器变成红色怎么办
- 十大宽带共享组建网络方式推荐
- Python递归小案例,斐波那契,阶乘等小案例
- 腾讯云服务器无法使用账号密码登录
- 信号完整性之眼图(eye)理解(一)
- ECSHOP去掉版权
- 前端使用setInterval定时器,使用clearInterval()清除时,清楚不彻底的原因。
- 造梦无双服务器维护12月17日,造梦无双Online官网版
- 运行wordcount程序