【什么是upper_bound 和 lower_bound】

简单来说lower_bound就是你给他一个非递减数列[first,last)和x,它给你返回非递减序列[first, last)中的第一个大于等于值x的位置。

而upper_bound就是你给他一个非递减数列[first,last)和x,它给你返回非递减序列[first, last)中的第一个大于值x的位置。

STL中实现这两种函数的算法就是二分。。。。。。

【upper_bound 和 lower_bound代码】

//STl中的lower_bound源代码
//这个算法中,first是最终要返回的位置
int lower_bound(int *array, int size, int key)
{
int first = 0, middle;
int half, len;
len = size; while(len > 0)
{
half = len >> 1;
middle = first + half;
if(array[middle] < key)
{
first = middle + 1;
len = len-half-1; //在右边子序列中查找
}
else
len = half; //在左边子序列(包含middle)中查找
}
return first;
}
//——————————upper_bound——————————————————
int upper_bound(int *array, int size, int key)
{
int first = 0, len = size-1;
int half, middle; while(len > 0){
half = len >> 1;
middle = first + half;
if(array[middle] > key) //中位数大于key,在包含last的左半边序列中查找。
len = half;
else{
first = middle + 1; //中位数小于等于key,在右半边序列中查找。
len = len - half - 1;
}
}
return first;
}
//______________End___________________________________________________________

【POJ 2785】

【题目原文】

The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet (a, b, c, d ) ∈ A x B x C x D are such that a + b + c + d = 0 . In the following, we assume that all lists have the same size n .

【题目大意】

给定各有n个整数的4个数列A,B,C,D。要从每一个数列中各去出一个数,使四个数的和为0.求出这样组合的个数。(当同一数列中有相同数字时按不同数字看待——博主注)

【输入描述】

有n行,一行4个数,分别是A[i],B[i],C[i],D[i]

【输入样例】

6
-45 22 42 -16
-41 -27 56 30
-36 53 -37 77
-36 30 -75 -46
26 -38 -10 62
-32 -54 -6 45

【输出描述】

一个数

【输出样例】

5

【博主注释】

有5种情况,分别是-45-27+42+30    26+30-10-46    -32+22+56-46    -32+30-75+77    -32-54+56+36

【题目分析】

我们把这些数对半分成AB与CD考虑。先从AB中取出a[i],b[i]后,为了使总和为0则需要从CD中取出c[i]+d[i]=a[i]-d[i]。因此将这些情况枚举出来,再用upper_bound和lower_bound进行二分即可。时间复杂度为O(n^2 logn)

【代码】

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=4001;
int n;
int a[maxn],b[maxn],c[maxn],d[maxn];
int cd[16000001];
int lower_bound(int *array, int size, int key)
{
int first = 0, middle;
int half, len;
len = size;
while(len > 0)
{
half = len >> 1;
middle = first + half;
if(array[middle] < key)
{
first = middle + 1;
len = len-half-1; //在右边子序列中查 找
}
else
len = half; //在左边子序列(包含middle)中查找
}
return first;
}
int upper_bound(int *array, int size, int key)
{
int first = 0, len = size-1;
int half, middle;
while(len > 0)
{
half = len >> 1;
middle = first + half;
if(array[middle] > key) len = half; //中位数大于key,在包含last的左半边序列中查找.
else
{
first = middle + 1; //中位数小于等于key,在右半边序列中查找。
len = len - half - 1;
}
}
return first;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>a[i]>>b[i]>>c[i]>>d[i];
//for(int i=0;i<n;i++) cin>>b[i];
//for(int i=0;i<n;i++) cin>>c[i];
//for(int i=0;i<n;i++) cin>>d[i];
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++) cd[i*n+j]=c[i]+d[j];
}
sort(cd,cd+n*n);
long long res=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
int CD=-(a[i]+b[j]);
res+=upper_bound(cd,cd+n*n,CD)-lower_bound(cd,cd+n*n,CD);
}
}
cout<<res;
return 0;
}

  

【刷题记录】 && 【算法杂谈】折半枚举与upper_bound 和 lower_bound的更多相关文章

  1. $2019$ 暑期刷题记录1:(算法竞赛DP练习)

    $ 2019 $ 暑期刷题记录: $ POJ~1952~~BUY~LOW, BUY~LOWER: $ (复杂度优化) 题目大意:统计可重序列中最长上升子序列的方案数. 题目很直接的说明了所求为 $ L ...

  2. PKUWC&SC 2018 刷题记录

    PKUWC&SC 2018 刷题记录 minimax 线段树合并的题,似乎并不依赖于二叉树. 之前写的草率的题解在这里:PKUWC2018 minimax Slay the Spire 注意到 ...

  3. DP刷题记录(持续更新)

    DP刷题记录 (本文例题目前大多数都选自算法竞赛进阶指南) TYVJ1071 求两个序列的最长公共上升子序列 设\(f_{i,j}\)表示a中的\(1-i\)与b中色\(1-j\)匹配时所能构成的以\ ...

  4. 刷题记录:[De1CTF 2019]Giftbox && Comment

    目录 刷题记录:[De1CTF 2019]Giftbox && Comment 一.知识点 1.sql注入 && totp 2.RCE 3.源码泄露 4.敏感文件读取 ...

  5. DP刷题记录

    目录 dp刷题记录 codeforces 706C codeforces 940E BZOJ3997 POJ2279 GYM102082B GYM102082D codeforces132C L3-0 ...

  6. 刷题记录:[GWCTF 2019]枯燥的抽奖

    目录 刷题记录:[GWCTF 2019]枯燥的抽奖 知识点 php伪随机性 刷题记录:[GWCTF 2019]枯燥的抽奖 题目复现链接:https://buuoj.cn/challenges 参考链接 ...

  7. 2021.12.19 eleveni的刷题记录

    2021.12.19 eleveni的刷题记录 0. 本次记录有意思的题 0.1 每个点恰好经过一次并且求最小时间 P2469 [SDOI2010]星际竞速 https://www.luogu.com ...

  8. 2021.12.16 eleveni的刷题记录

    2021.12.16 eleveni的刷题记录 1. 数论 https://www.luogu.com.cn/problem/P2532 1.1卡特兰数 https://www.luogu.com.c ...

  9. PE刷题记录

    PE刷题记录 PE60 / 20%dif 这道题比较坑爹. 所有可以相连的素数可以构成一张图,建出这张图,在其中找它的大小为5的团.注意上界的估算,大概在1W以内.1W内有1229个素数,处理出这些素 ...

随机推荐

  1. UvaLA 3938 "Ray, Pass me the dishes!"

                            "Ray, Pass me the dishes!" Time Limit: 3000MS   Memory Limit: Unkn ...

  2. 第3月第21天 nsclassfromstring返回null SVN报错:clean the working copy and then retry the operation

    1. xcodeproj工程损坏时,.m文件没有加入编译. 2. SVN报错:clean the working copy and then retry the operation http://bl ...

  3. Bookshop(一)数据库连接

    连接池配置文件db.properties配置 1.新建一个普通文件->改名为db.properties(后缀)手动添加属性 一般为数据库驱动类.数据库连接地址.用户名.用户密码 driver=c ...

  4. mac php环境启动

    mac 环境下,用brew安装php相关环境启动命令 说明 这里php,mysql,nginx都是用brew安装,安装目录默认,在Cellar下面 php-fpm 带配置重启 /*注意权限,加 sud ...

  5. 再说表单验证,在Web Api中使用ModelState进行接口参数验证

    写在前面 上篇文章中说到了表单验证的问题,然后尝试了一下用扩展方法实现链式编程,评论区大家讨论的非常激烈也推荐了一些很强大的验证插件.其中一位园友提到了说可以使用MVC的ModelState,因为之前 ...

  6. Linux kernel4.4.12 添加make menuconfig 可选项

    Linux kernel 源码添加可选项 闲来无事,顺便记录一篇在Linux kernel make menuconfig 内添加一个可选项. 说不定将来就要用到这个东西呢. linux kernel ...

  7. PHP获取某月天数

    方式一: <?php function days($year,$month){ if($month<10){ $month = '0'.$month; } if($month == 12) ...

  8. Lodash.js的库

    1.orderBy _order(数组,排序对象,["asc"]升序或者["desc"]降序)

  9. ListView加载性能优化---ViewHolder---分页

    ListView是Android中一个重要的组件,可以使用它加列表数据,用户可以自己定义列表数据,同时ListView的数据加载要借助Adapter,一般情况下要在Adapter类中重写getCoun ...

  10. Ajax加载菊花loding效果

    Ajax 异步请求的时候,一般都会利用一个动态的 gif小图片来制作一个Ajax Loading ,以便增加用户体验. 这里我们使用Spin.js ,该 js 脚本压缩后5k,可以不用任何图片,任何外 ...