lower_bound

hdu 6695 Welcome Party 枚举 set

谁都会走 提交于 2019-11-28 19:18:37
把所有人按照sing从大到小排序,然后枚举sing值最高的人i,比他高的必须得去talk,维护必须去talk的这波人的最大值,作为maxn。 然后两个情况,如果maxn>=sing[i],那么i作为sing最高的人情况下,显然talk中的最大值不可能小于maxn,我们再怎么往talk组加人,也只可能会让差距变大,所以把maxn - sing[i]和答案取min。 如果maxn < sing[i],我们就去找i+1到n,这些人中,talk最接近sing[i]的两个人,一个大于等于sing[i],一个小于等于sing[i],用set中lower_bound实现,对于小于情况加入负数即可。注意这两个人必须都得大于maxn,才有意义。然后继续取min。 maxn初值必须得是负无穷,要不然,第一个人的sing可能跟初值为0的maxn取出一个不存在的情况。被这个边界卡了一下午.... 1 #include <cstdio> 2 #include <set> 3 #include <algorithm> 4 using namespace std; 5 typedef long long ll; 6 struct peo 7 { 8 ll sing,talk; 9 friend bool operator < (peo a,peo b) 10 { 11 return a.sing > b

lower_bound() 函数使用详解

白昼怎懂夜的黑 提交于 2019-11-28 08:37:48
简介 lower_bound()函数是用来求一个容器中,第一个大于等于所要查找的元素的地址,具体的原理是二分查找,因此它只能用于 非降序序列 。 他有三个参数,第一个参数是容器的初始地址,第二个参数是容器的末尾位置,第三个参数是所要查找的元素值。 返回值是第一个大于等于所要查找的元素的地址。 具体使用 vector<int> v; v.push_back(1), v.push_back(2), v.push_back(3); //打印 2 的位置 cout << lower_bound(v.begin(), v.end(), 2) - v.begin(); int a[] = {1,2,3}; //打印 2 的位置 cout << lower_bound(a, a + 3, 2) - a; 来源: https://www.cnblogs.com/woxiaosade/p/11402748.html

Glider(前缀和+二分)

a 夏天 提交于 2019-11-28 04:56:04
题目链接: Glider Gym-101911B 解题分析:下落的高度一定,是h。在没有气流的地方每秒下落1;所以可以转化为经过无气流地带的时间总长为h。      那么很显然从一个有气流地带的开始,选择下落,那么问题来了,一个一个去试然后一个一个计算他的路径去维护一个最大值吗?未免太过麻烦,所给数据有      那么大。 解题关键 : 二分+前缀和 二分查找用:lower_bound()       int x=lower_bound(a, a+n, val)-a;       其中i返回值为数组元素值大于等于val的第一个下标。相应地,如果数组中的所有元素的值都小于val,则返回值为数组最后一个元素下标的下一个下标 具体见代码注释: /* 所给的数据:气流范围是按顺序给的,方便直接求前缀和*/ # include <iostream> # include <stdio.h> # include <string.h> # include <string> # include <iomanip> # include <algorithm> # include <ctime> # include <cmath> # include <climits> # include <cstdlib> # include <utility> # include <bitset> #

hdu第九场多校

廉价感情. 提交于 2019-11-28 04:53:27
02:线段树两次扫描 #include<bits/stdc++.h> #include<vector> using namespace std; #define maxn 300005 struct Line{int x,y;char s[10];}a[maxn]; int n,m,K; int cmp1(Line &a,Line &b){return a.y<b.y;} int cmp2(Line &a,Line &b){return a.y>b.y;} int x[maxn],tot; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int lazy[maxn<<2]; void pushdown(int rt){ if(lazy[rt]){ lazy[rt<<1]+=lazy[rt]; lazy[rt<<1|1]+=lazy[rt]; lazy[rt]=0; } } void build(int l,int r,int rt){memset(lazy,0,sizeof lazy);} void update(int L,int R,int val,int l,int r,int rt){ if(L<=l && R>=r){ lazy[rt]++;return; } int m=l+r>>1; pushdown(rt); if

P5445 [APIO2019]路灯(树套树)

[亡魂溺海] 提交于 2019-11-28 04:13:05
P5445 [APIO2019]路灯 转化为平面上的坐标 ( x , y ) , set维护连续区间. 用树套树维护矩阵加法,单点查询。 注意维护矩阵差分的时候, $(x,y,v)$是对$(x,y)(n+1,n+1)$的矩阵做出贡献 #include<iostream> #include<cstdio> #include<cstring> #include<set> #define ri register int using namespace std; int read(){ char c=getchar(); ri x=0; while(c<'0'||c>'9') c=getchar(); while('0'<=c&&c<='9') x=x*10+c-48,c=getchar(); return x; } #define N 600005 #define W 20000005 struct E{ int l,r; E(int A,int B):l(A),r(B){} bool operator < (const E &G) const{return r<G.r;} };set<E> g; set<E>::iterator it; int n,T,a[N]; char opt[9],cc[N]; int cnt,rt[N],lc[W],rc[W],s[W]; #define

mex(线段树+离散化)

て烟熏妆下的殇ゞ 提交于 2019-11-27 21:43:28
题目描述: 给你一个无限长的数组,初始的时候都为0,有3种操作: 操作1是把给定区间 [ l , r ] [l,r] 设为1, 操作2是把给定区间 [ l , r ] [l,r] 设为0, 操作3把给定区间 [ l , r ] [l,r] 0,1反转。 一共n个操作,每次操作后要输出最小位置的0。 题解: 经过分析观察,可以发现,答案只有可能是 1 , l , r + 1 所以我们开一个数组记录1,以及所有的l,r,r+1,并离散化 然后用线段树模拟操作即可 这里有两种思路: 一种是记录某一区间内0的最小位置和1的最小位置,反转时互换两个位置 #include<iostream> #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int N=1e5+5; const int maxn=3e5+5; int n,m;ll a[maxn]; struct que{ int op;ll l,r; }q[N]; int s0[maxn<<2],s1[maxn<<2],lazy[maxn<<2],rev[maxn<<2]; void pushup(int u){ if(s0[u*2]) s0[u]=s0[u*2]; else if(s0[u*2+1]) s0[u]=s0

[USACO09DEC]音符Music Notes (二分、STL)

南笙酒味 提交于 2019-11-27 21:15:17
https://www.luogu.org/problem/P2969 题目描述 FJ is going to teach his cows how to play a song. The song consists of N (1 <= N <= 50,000) notes, and the i-th note lasts for Bi (1 <= Bi <= 10,000) beats (thus no song is longer than 500,000,000 beats). The cows will begin playing the song at time 0; thus, they will play note 1 from time 0 through just before time B1, note 2 from time B1 through just before time B1 + B2, etc. However, recently the cows have lost interest in the song, as they feel that it is too long and boring. Thus, to make sure his cows are paying attention, he asks them Q (1 <= Q <

P5445 [APIO2019]路灯

℡╲_俬逩灬. 提交于 2019-11-27 17:48:30
传送门 · 对于询问 $(a,b)$ ,感觉一维很不好维护,考虑把询问看成平面上的一个点,坐标为 $(a,b)$ 每个坐标 $(x,y)$ 的值表示到当前 $x$ 和 $y$ 联通的时间和 考虑一个修改的贡献,它其实就是把左边一段区间 $[l,x]$ 和右边一段区间 $[x+1,r]$ 联通或断开 放到平面上发现其实就是横坐标在 $[l,x]$ ,纵坐标在 $[x+1,r]$ 的矩形里修改,那么矩形左下角为 $[l,x+1]$,右上角为 $[x,r]$ 如果每个时间点都把相应矩形 $+1$ 的话显然是不可行的,考虑起点和终点的时间差 如果当前操作是联通,设当前时间为 $t$,则把相应矩形 $-t$,如果是断开则把矩形加 $t$ 这样我们询问时直接矩形单点查值即可,但是要注意,如果查询时当前区间仍然联通,那么对应矩形还没加 $t$ ,我们查完值以后答案还要再加 $t$ 矩形加具体就是差分成四个前缀修改,查询的时候直接查左下所有位置的和即可 如果把左下角为 $(xa,ya)$,右上角 $(xb,yb)$ 的闭区间都加一个 $v$,那么其实就是把 $(0,0),(xa,ya)$ 加一个 $v$,$(0,0),(xa,yb+1)$ 减 $v$,$(0,0),(xb+1,ya)$ 减 $v$,$(0,0),(xb+1,yb+1)$ 加 $v$ 二维平面加一维时间轴, $CDQ$ 分治即可