Difference in two ways of using lower_bound [C++]std::set::lower_bound与std::lower_bound

时间:2022-07-25
本文章向大家介绍Difference in two ways of using lower_bound [C++]std::set::lower_bound与std::lower_bound,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

缘起:Codeforces Round #555 (Div. 3), problem: (E) Minimum Array 这道题目难度不大,大概在div2 C题左右

但是有个关键点就是stl中lowerbound和set自带的lowerbound差别,

很naive的我想着这两个都是o(logn)的,事实上,t了无数发后才发现标程是 s.lower_bound(x)而我是(s.begin(),s.end(),x) 差别是我的是o(n),标程是logn级别的

set输入时已经建好树 而模板lowerbound要多一个类似建树的过程

可以简单的记住 algorithm的是通用的的lower_bound算法 set的是专有的s.lower_bound(x)算法 肯定set快一点

STL的设计是通用的和灵活的。

有很多容器,它们都需要支持通用操作,比如遍历元素、排序、查找元素等等。因此,STL并没有在所有容器中实现多个方法container.sort(),而是提供了一个统一的函数std::sort(),它可以用于对不同的容器进行排序,而不是在所有容器中实现多个方法container.sort(),其中大多数方法都使用相同的算法。函数std::lower_bound()也是如此。

然而,由于容器的内部模型,并不是所有的容器都使用相同的算法。例如,不能像在vector中那样以随机顺序访问list中的元素。对于这种情况,有专门为容器设计的方法。因此list有方法list::sort(),它使用特定于链表结构的算法。

set和lower_bound()也是一样。有一个统一的函数std::lower_bound(),它在随机访问迭代器上的O(logN)中工作,在其他迭代器上的O(N)中工作。容器std::set具有双向迭代器,不能提供对其成员的随机访问。所以统一的std::lower_bound()在O(N)中工作。而容器集是二叉搜索树,可以使用不同的算法在O(logN)中找到下界,具体针对std::set的内部结构。它在方法集::lower_bound()中实现,在O(logN)中工作。

附上AC代码

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#include<unordered_set>
#define rg register ll
#define inf 2147483647
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define ll long long
#define maxn 200005
const double eps = 1e-8;
using namespace std;
inline ll read()
{
	char ch = getchar(); ll s = 0, w = 1;
	while (ch < 48 || ch>57) { if (ch == '-')w = -1; ch = getchar(); }
	while (ch >= 48 && ch <= 57) { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); }
	return s * w;
}
inline void write(ll x)
{
	if (x < 0)putchar('-'), x = -x;
	if (x > 9)write(x / 10);
	putchar(x % 10 + 48);
}
ll n, a[maxn], ans[maxn], minn = maxn;
multiset<ll>p;
 
int main()
{
	n = read();
	for (rg i = 1; i <= n; i++)a[i] = read();
	for (rg i = 1; i <= n; i++)
	{
		ll x = read();
		minn = min(x, minn);
		p.insert(x);
	}
	for (rg i = 1; i <= n; i++)
	{
		ll temp = n - a[i];
		if (p.lower_bound(temp) == p.end())
		{
			ans[i] = (a[i] + *p.begin()) % n;
			p.erase(p.begin());
 
		}
		else
		{
			temp = *(p.lower_bound(temp));
			//cout << temp << endl;
				ans[i] = (a[i] + temp) % n;
				p.erase(p.lower_bound(temp));
				//cout << n-temp << " "<<p.size()<<endl;
		}
	}
	for (rg i = 1; i <= n; i++)
	{
		i == n ? cout << ans[i] : cout << ans[i] << " ";
	}
	return 0;
}