题目大意:
有很多座建筑([ 1 , 10^8 ]),摧毁n座(可重复),m次查询,查询现在第i座的原先编号。
思路:考虑到1<=n<=50000,将连续的建筑物当做一个整体,分别求每块的总建筑物数。
对其进行二分查找。复杂度o(nlogn)。
#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 50010
int x[MAXN];
struct node{
int l,r,c;
}coo[MAXN];
int main()
{
int n,m,i,l,r,mid,pos;
while(scanf("%d",&n)!=EOF)
{
for(i=0;i<n;++i)
scanf(" %d",&x[i]);
sort(x,x+n);
n = unique(x,x+n) - x;
i = 0;
pos = 1;
while(i<n)
{
coo[i+1].l = pos;
coo[i+1].r = x[i];
coo[i+1].c = coo[i].c + x[i] - pos;
pos = x[i] + 1;
i++;
}
coo[i+1].l = pos;
coo[i+1].r = 100000000;
coo[i+1].c = coo[i].c + 100000000 - pos;
i = 0;
/* while(i<=n)
{
printf("%d %d %d\n",coo[i+1].l,coo[i+1].r,coo[i+1].c);
i++;
}*/
scanf(" %d",&m);
while(m--)
{
scanf(" %d",&pos);
l = 1;
r = n + 1;
while(l<=r)
{
mid = (l+r)>>1;
if(pos>coo[mid].c)
l = mid + 1;
else
r = mid - 1;
}
// printf("!!! %d\n",l);
// if(l>n+1)
// printf("0\n");
// else
// printf("%d\n",pos - (coo[l].c - (coo[l].r - coo[l].l)) + coo[l].l - 1);
printf("%d\n",pos - (coo[l].c - coo[l].r) - 1);
}
printf("\n");
}
return 0;
}