传送门
题目大意:给一个01序列.支持查询i位置最大的连续1子串的长度.
可以二分+树状数组.不过不用那么麻烦,直接暴力分块就好了.
只需要维护一个信息.块上是否只有1.不是的话就暴力找到第一个0.是的话就找下一个块.这样子复杂度就是O(nsqrt(n))的.
HDU 和 POJ上的老题都会有很多说的不清不楚的点.一个点可能多次被摧毁,但修复了之后就不用再次修复了,还有多组数据输入.
代码(虽然代码有点长,但思考难度几乎为0)
#pragma GCC optimize(3)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <string.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cmath>
using namespace std;
const int N = 5e4+10;
inline LL read(){
LL x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void write(LL k) {
if (k < 0)
putchar('-'), k = -k;
if (k >= 10)
write(k / 10);
putchar(k % 10 + '0');
}
int n,m,blo,num,a[N],L[N],R[N],pos[N],v[N];
void build(){
blo = sqrt(n);
num = n/blo;
fir(i,1,num){
L[i] = (i-1)*blo+1;
R[i] = i*blo;
}
if(n % blo){
num++;
L[num] = R[num-1]+1;
R[num] = n;
}
fir(i,1,num){
v[i] = 1;
fir(j,L[i],R[i]){
a[j] = 1;
pos[j] = i;
}
}
}
int s[N],idx=0;
void change(int l,int x){
int p = pos[l];
a[l] = x;
if(x){
fir(i,L[p],R[p]){
if(a[i] != 1){
v[p] = 0;
return;
}
}
v[p] = 1;
}
else v[p] = 0;
}
int query(int l){
int res = 0;
int p = pos[l];
bool f = 0;
if(a[l]){
afir(i,l,L[p]){
if(!a[i]){
f = 1;
break;
}
res++;
}
int left = p;
if(!f){
left--;
while(left && v[left]){
res += R[left] - L[left] + 1;
left--;
}
if(left){
afir(i,R[left],L[left]){
if(!a[i]) break;
res++;
}
}
}
int right = p;
f = 0;
if(l == R[p] && !a[l]) f = 1;
fir(i,l+1,R[p]){
if(!a[i]){
f = 1;
break;
}
res++;
}
if(!f){
right++;
while(right <= num && v[right]){
res += R[right] - L[right] + 1;
right++;
}
if(right <= num){
fir(i,L[right],R[right]){
if(!a[i]) break;
res++;
}
}
}
}
return res;
}
int main(){
ios::sync_with_stdio(false);
while(cin >> n >> m){
build();
idx = 0;
while(m--){
char op;
int x;
cin >> op;
if(op == 'R'){
while(idx && a[s[idx]]) idx--;
if(!idx) continue;
change(s[idx],1);
idx--;
}
else{
cin >> x;
if(op == 'Q'){
write(query(x));
puts("");
}
else{
change(x,0);
s[++idx] = x;
}
}
//fir(i,1,n) cout << a[i] << " ";
//puts("");
}
}
return 0;
}