lower_bound和upper_bound函数的使用

文章目录

  • 介绍
  • Range Count Query
  • Auto-Complete
    • make_pair
    • sort对pair进行排序


介绍

1.对于一个从小到大排序的数组,lower_bound(begin,end,x) 查找成功返回的是从地址begin到end-1中第一个大于或者等于x的地址,减去begin恰好为数组下标。查找失败返回end。
2.对于一个从小到大排序的数组,upper_bound(begin,end,x) 查找成功返回的是从地址begin到end-1中第一个大于x的地址,减去begin恰好为数组下标。查找失败返回end。
3.对于一个从大到小排序的数组,lower_bound(begin,end,x,greater < int >()) 查找成功返回的是从地址begin到end-1中第一个小于或者等于x的地址,减去begin恰好为数组下标。查找失败返回end。
4.对于一个从大到小排序的数组,upper_bound(begin,end,x,greater< int >()) 查找成功返回的是从地址begin到end-1中第一个小于x的地址,减去begin恰好为数组下标。查找失败返回end。
5.upper_bound和lower_bound查找是通过二分查找的,所以查找序列必须是排好序的。

#include
#include
#include
using namespace std;
int a[5]={0,1,1,2,3};
vector<int> v={0,1,1,2,3};

int main()
{
	int ans=0;
	ans=lower_bound(a,a+5,1)-a;
	cout<<ans<<endl;//1
	ans=upper_bound(a,a+5,1)-a;
	cout<<ans<<endl;//3
	ans=lower_bound(a,a+5,4)-a;
	cout<<ans<<endl;//5
	ans=upper_bound(a,a+5,4)-a;
	cout<<ans<<endl;//5
	
	ans=lower_bound(v.begin() ,v.end() ,1)-v.begin();
	cout<<ans<<endl;//1
	ans=upper_bound(v.begin() ,v.end() ,1)-v.begin();
	cout<<ans<<endl;//3
	ans=lower_bound(v.begin() ,v.end() ,4)-v.begin() ;
	cout<<ans<<endl;//5
	ans=upper_bound(v.begin() ,v.end() ,4)-v.begin() ;
	cout<<ans<<endl;//5
	
	//a[5]={3,2,1,1,0}
	sort(a,a+5,greater<int>());
	ans=lower_bound(a,a+5,1,greater<int>())-a;
	cout<<ans<<endl;//2
	ans=upper_bound(a,a+5,1,greater<int>())-a;
	cout<<ans<<endl;//4
	ans=lower_bound(a,a+5,4,greater<int>())-a;
	cout<<ans<<endl;//0
	
	return 0;
}

Range Count Query

Range Count Query
时间限制: 2.000 Sec 内存限制: 1024 MB
题目描述
You are given a sequence of length N: A=(A1,…,AN).Answer Q queries given in the following format.
You are given integers L, R, and X.
Find the number of elements among AL, …, AR whose values are equal to X.
Constraints
1 ≤ N ≤ 2× 105
1 ≤ Ai ≤ N
1 ≤ Q ≤ 2× 105
1≤L ≤ R ≤ N, 1 ≤ X ≤ N, for each query.
All values in input are integers.

输入
Input is given from Standard Input in the following format:
N
A1 A2 … AN
Q
Query1
Query2
.
.
.
QueryQ

输出
Print Q lines, the i-th of which contains the answer to the i-th query.

样例输入 Copy
【输入样例1】

5
3 1 4 1 5
4
1 5 1
2 4 3
1 5 2
1 3 3

样例输出 Copy
【输出样例1】

2
0
0
1

提示
【样例1解释】
In the first query, two of (A1,A2,A3,A4,A5)=(3,1,4,1,5) have values equal to 1.
In the second query, zero of (A2,A3,A4)=(1,4,1) have values equal to 3.


题目大意就是在数组a中寻找下标l到r元素中有多少个跟x相等,直接求显然会超时,于是可以开一个vector数组,v[x]里面存放数组a中跟x相等的元素下标值,每次查找的时候找到v[x]中>=l&&<=r有多少个元素即可。

#include
#include 
#include
using namespace std;
const int N=2e5+10;
vector<int>v[N];

int main()
{
	int n;cin>>n;
	for(int i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		v[x].push_back(i); 
	}
	int q;cin>>q;
	while(q--)
	{
		int ll,rr,x;scanf("%d%d%d",&ll,&rr,&x);
		//大于等于ll的元素下标位置 
		int i1=lower_bound(v[x].begin() ,v[x].end() ,ll)-v[x].begin() ;
		//大于rr的元素下标位置 
		int i2=upper_bound(v[x].begin() ,v[x].end() ,rr)-v[x].begin() ;
		//相减即区间内元素个数 
		int ans=i2-i1;
		printf("%d\n",ans);
	}
	
	return 0;
}

Auto-Complete

Auto-Complete
时间限制: 1.000 Sec 内存限制: 64 MB

题目描述
Bessie the cow has a new cell phone and enjoys sending text messages,although she keeps making spelling errors since she has trouble typing on such a small screen with her large hooves. Farmer John has agreed to help her by writing an auto-completion app that takes a partial word and suggests how to complete it.

The auto-completion app has access to a dictionary of W words, each consisting of lowercase letters in the range a…z, where the total number of letters among all words is at most 1,000,000. The app is given as input a list of N partial words (1 <= N <= 1000), each containing at most 1000 lowercase letters. Along with each partial word i, an integer K_i is also provided, such that the app must find the (K_i)th word in alphabetical order that has partial word i as a prefix. That is, if one ordered all of the valid completions of the ith partial word, the app should output the completion that is (K_i)th in this sequence.
输入

  • Line 1: Two integers: W and N.
  • Lines 2…W+1: Line i+1: The ith word in the dictionary.
  • Lines W+2…W+N+1: Line W+i+1: A single integer K_i followed by a partial word.
    输出
  • Lines 1…N: Line i should contain the index within the dictionary (an integer in the range 1…W) of the (K_i)th completion (in alphabetical order) of the ith partial word, or -1 if there are less than K_i completions.
    样例输入 Copy
10 3
dab
ba
ab
daa
aa
aaa
aab
abc
ac
dadba
4 a
2 da
4 da

样例输出 Copy

3
1
-1

提示
The completions of a are {aa,aaa,aab,ab,abc,ac}. The 4th is ab, which is listed on line 3 of the dictionary. The completions of da are {daa,dab,dadba}. The 2nd is dab, listed on line 1 of the dictionary. There is no 4th completion of da.

题目大意是对于每次查找k和string t,找到题目所给字典里以t为前缀的单词里第k个单词,输出该单词在原字典中的位置。
先用pair保存下来字典,以及string的位置,然后根据字典序对string进行排序,lower_bound函数进行查找第一个以t为前缀的字符串在排序后的pair数组中所在的位置,加上k-1即所查找的字符串所在位置,最后判断一下该位置是否合法即可:

#include
#include
using namespace std;
const int N=10010;
pair<string,int>s[N];

int check(string l,string r)//判断r是不是l的前缀 
{
	if(r.size() >l.size() ) return 0;
	return l.substr(0,r.size() )==r; 
}

int main()
{
	int w,n;cin>>w>>n;
	for(int i=0;i<w;i++)
	{
		cin>>s[i].first ;
		s[i].second =i+1;
	}
	sort(s,s+w);
	while(n--)
	{
		int k;string t;
		cin>>k>>t;
		int i=k-1+lower_bound(s,s+w,pair<string,int>(t,0))-s;
		if(i>=w||!check(s[i].first ,t))puts("-1");
		else printf("%d\n",s[i].second );
	}
	
	return 0;
}

make_pair

无需写出型别, 就可以生成一个pair对象
例:
make_pair(t,0);
而不必费力写成:
pair(t,0);

当有必要对一个接受pair参数的函数传递两个值时, make_pair()尤其显得方便,
void f(make_pair(t,0));

sort对pair进行排序

pair 默认对first升序,当first相同时对second升序;

你可能感兴趣的:(算法,c++,开发语言)