题意:求0所在位置两点连续0的个数,不断更新某个点,将这个点变成0或1
用数状数组维护这个表,变成0,1就更新某个点,这是树状数组的特长。查询的时候,对两边二分就行了
//
// main.cpp
// poj2892
//
// Created by He Xilin on 12-4-30.
// Copyright 2012年 UESTC,ZSC. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 50000;
int c[MAXN + 10];
void Delete(int x)//树状数组更新点
{
while(x<=MAXN)
{
c[x]++;
x += x & ( x ^ (x - 1));
}
}
void recover(int x)//树状数组更新点
{
while(x<=MAXN)
{
c[x]--;
x += x & (x ^ (x - 1));
}
}
int sum(int x)//树状数组求和
{
int ans = 0;
while(x > 0)
{
ans += c[x];
x -= x & (x ^ (x - 1));
}
return ans;
}
int binary(int x, int s, int t,bool isSecond)//二分左边的区间
{
if(sum(t) == 0)
{
return 0;
}
int ans = -1;
int total = sum(x);
int mid;
while(s <= t)
{
mid = ((s + t) >> 1);
int flag = sum(mid);
if(total - flag == 0)
{
ans = mid;
t = mid - 1;
}
else
{
if(isSecond == false)
s = mid + 1;
else
t = mid - 1;
}
}
return ans == -1 ? mid : ans;
}
int binary2(int x, int s, int t,bool isSecond)//二分右边的区间
{
int total = sum(x);
int ans = -1;
if(sum(t) - total == 0)
{
return t + 1;
}
int mid;
while(s <= t)
{
mid = ((s + t) >> 1);
int flag = sum(mid);
if(flag - total == 1)
{
//return mid;
ans = mid;
t = mid - 1;
}
else if(flag - total < 1)
{
s = mid + 1;
}
else
{
t = mid - 1;
}
}
return ans == -1 ? mid: ans;
}
int query(int n,int x)//查询
{
if(sum(x) - sum(x - 1) != 0)
{
return 0;
}
int s = 1;
int t = x - 1;
int mid1 = binary(x,s, t,false);
s = x + 1;
t = n;
int mid2 = binary2(x, s, t,true);
//printf("%d, %d\n",mid1,mid2);
return mid2 - mid1 - 1;
}
int main (int argc, const char * argv[])
{
//freopen("poj2892.in", "r", stdin);
int n,m;
while(scanf("%d %d",&n,&m) != EOF)
{
int sta[MAXN + 10];
int cnt = -1;
memset(c,0,sizeof(c));
int i;
char ch[2];
int num;
for(i = 0; i < m; i++)
{
scanf("%s",ch);
if(strcmp(ch,"D") == 0)
{
scanf("%d",&num);
sta[++cnt] = num;
Delete(num);
}
else if(strcmp(ch,"R") == 0)
{
//scanf("%d",&num);
recover(sta[cnt--]);
}
else
{
scanf("%d",&num);
if(num == 6)
{
int debug = 1;
}
int ans = query(n,num);
printf("%d\n",ans);
}
}
}
return 0;
}