原题地址:点击打开链接
题意:有1-n个村子,D- x表示摧毁x村,R表示修好刚被摧毁的村子,Q-x,表示询问你x所在的村子附近一共有多少村子是没有摧毁的。
思路:这种询问的题型一般直接都会想到用树状数组做,我们可以用树状数组记录被摧毁的村子的和,p[x],表示1-x共有多少村子被摧毁,
然后我们可以用二分查找进行解答,当你询问x村时,如果x村已经被摧毁,那就输出0,否则先找出1-x村有多少被摧毁,假设n个被摧毁,这个时候我们就可以用
二分查找,找出x最小为多少时有n个村子被摧毁,x最大为多少时有多少村子被摧毁,答案就是 xMax-xMin.
树状数组详解:点击打开链接
#include<stdio.h>
#include<string.h>
using namespace std;
int p[50010],n;
int lowbit(int i)
{
return i&(-i);
}
void add(int i,int x)
{
while(i<=n)
{
p[i]+=x;
i+=lowbit(i);
}
}
int sum(int i)
{
int res=0;
while(i>=1)
{
res+=p[i];
i-=lowbit(i);
}
return res;
}
int binary_search(int x)
{
int left=0,right=n+1;
while(left<right)
{
int mid=(left+right)/2;
if(sum(mid)>=x)
{
right=mid;
}
else
{
left=mid+1;
}
}
return right;
}
int main()
{
int i,m,x,d[50010],cnt;
bool mark[50010];
char str[10];
while(scanf("%d%d",&n,&m)!=EOF)
{
cnt=0;
memset(p,0,sizeof(p));
memset(mark,false,sizeof(mark));
for(i=0;i<m;i++)
{
scanf("%s",str);
if(str[0]=='D')
{
scanf("%d",&x);
add(x,1);
mark[x]=true;
d[cnt++]=x;
}
else if(str[0]=='R')
{
x=d[--cnt];
add(x,-1);
mark[x]=false;
}
else
{
scanf("%d",&x);
if(mark[x]==true)
{
printf("0\n");
continue;
}
x=sum(x);
int a=binary_search(x);
int b=binary_search(x+1);
int res=b-a-1;
printf("%d\n",res);
}
}
}
return 0;
}