数据结构,范围查询
#include <stdio.h>
using namespace std;
#define maxn 500000
int s[maxn], q1[maxn], q2[maxn], recordleft[maxn], recordright[maxn];
int searchleft(int*s, int n, int e)
{
int hi = n, lo = 0, mi;
while (lo<hi)
{
mi = (hi + lo) / 2;
if (e<s[mi])hi = mi;
else if (s[mi] <= e)lo = mi + 1;
}
if (lo == 0)return --lo;
else return (s[--lo] == e) ? --lo : lo;
}
int searchright(int*s, int n, int e)
{
int hi = n, lo = 0, mi;
while (lo < hi)
{
mi = (hi + lo) / 2;
if (e < s[mi])hi = mi;
else if (s[mi] <= e)lo = mi + 1;
}
return --lo;
}
void unqiue(int*s, int&n)
{
int*pre = &s[0], *pconst = &s[0], p;
for (auto i = 1; i<n; i++)
{
if ((p = s[i]) == *pre);
else *(++pre) = p;
}
n = pre - pconst + 1;
}
void merge(int*s, int lo, int mi, int hi)
{
int*pre = new int[mi - lo];
for (auto i = 0; i<mi - lo; i++)pre[i] = s[lo + i];
int j = 0, lenght_pre = mi - lo;
while (j<lenght_pre&&mi<hi)
{
if (pre[j]<s[mi])s[lo++] = pre[j++];
else s[lo++] = s[mi++];
}
if (j == lenght_pre && mi<hi);
else while (j<lenght_pre)s[lo++] = pre[j++];
delete[] pre;
}
void mergesort(int*s, int lo, int hi)
{
int mi = (lo + hi) / 2;
if (1<hi - lo) {
mergesort(s, lo, mi);
mergesort(s, mi, hi);
merge(s, lo, mi, hi);
}
else;
}
int main()
{
int n, m, i = 0, j = 0;
scanf("%d%d", &n, &m);
if (0 <= n && n <= maxn && 0 <= m && m <= maxn)
{
int num = m, nn = n;
while (n--)
{
scanf("%d", &s[i]);
if(0<=s[i]&&s[i]<=10000000)i++;
else continue;
}
if (nn>1)mergesort(s, 0, nn);
if (nn>1)unqiue(s, nn);
while (m--)
{
scanf("%d%d", &q1[j], &q2[j]);
if(q1[j]<=q2[j])j++;
else continue
;
}
int l = 0, left = 0, right = 0;
while (l++<num)
{
recordleft[l] = searchleft(s, nn, q1[left++]);
recordright[l] = searchright(s, nn, q2[right++]);
printf("%d\n", recordright[l] - recordleft[l]);
}
}
else return 0;
return 0;
}
以上是正确答案
说明,提交的时候要提交cpp文件。
如果是提交压缩包,可能会出错。
还有就是,这里的限定,其实都是要你进行判定的。(即,不是已经给好的,是要你考虑到的)
这里用到了2分查找,端点判定,归并排序,有序的唯一化这四个知识点