#线段树#CF1371F Raging Thunder
分析
其实掉出区间边界或洞内就算消失,最终球只会掉到最左侧的 <,中间的 ><,和最右侧的 >
在线段树上维护左右边界上最长的<,>,<>,><和区间内最长的<>,><即可
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
const int N=500011; int a[N],n,Q,lazy[N<<2];
struct rec{int ll,lr,rl,rr,llr,lrl,rlr,rrl,lrw,rlw;}w[N<<2];
int iut(){
int ans=0,f=1; char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans*f;
}
void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
void ptag(int k){
swap(w[k].ll,w[k].lr);
swap(w[k].rl,w[k].rr);
swap(w[k].rlw,w[k].lrw);
swap(w[k].llr,w[k].lrl);
swap(w[k].rlr,w[k].rrl);
lazy[k]^=1;
}
rec pup(rec A,rec B,int l,int mid,int r){
rec C;
C.rlw=max(A.rlw,B.rlw);
if (A.rr&&B.ll) C.rlw=max(C.rlw,A.rr+B.ll);
if (A.rrl) C.rlw=max(C.rlw,A.rrl+B.ll);
if (B.lrl) C.rlw=max(C.rlw,B.lrl+A.rr);
C.lrw=max(A.lrw,B.lrw);
if (A.rl&&B.lr) C.lrw=max(C.lrw,A.rl+B.lr);
if (A.rlr) C.lrw=max(C.lrw,A.rlr+B.lr);
if (B.llr) C.lrw=max(C.lrw,B.llr+A.rl);
if (A.lr==mid-l+1) C.lr=A.lr+B.lr;
else C.lr=A.lr;
if (A.ll==mid-l+1) C.ll=A.ll+B.ll;
else C.ll=A.ll;
if (B.rr==r-mid) C.rr=B.rr+A.rr;
else C.rr=B.rr;
if (B.rl==r-mid) C.rl=B.rl+A.rl;
else C.rl=B.rl;
if (A.llr==mid-l+1) C.llr=A.llr+B.lr;
else if (A.ll==mid-l+1&&max(B.lr,B.llr)) C.llr=A.ll+max(B.lr,B.llr);
else C.llr=A.llr;
if (A.lrl==mid-l+1) C.lrl=A.lrl+B.ll;
else if (A.lr==mid-l+1&&max(B.ll,B.lrl)) C.lrl=A.lr+max(B.ll,B.lrl);
else C.lrl=A.lrl;
if (B.rlr==r-mid) C.rlr=B.rlr+A.rl;
else if (B.rr==r-mid&&max(A.rl,A.rlr)) C.rlr=B.rr+max(A.rl,A.rlr);
else C.rlr=B.rlr;
if (B.rrl==r-mid) C.rrl=B.rrl+A.rr;
else if (B.rl==r-mid&&max(A.rr,A.rrl)) C.rrl=B.rl+max(A.rr,A.rrl);
else C.rrl=B.rrl;
return C;
}
void build(int k,int l,int r){
if (l==r){
if (a[l]) w[k].lr=w[k].rr=1;
else w[k].ll=w[k].rl=1;
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
w[k]=pup(w[k<<1],w[k<<1|1],l,mid,r);
}
void update(int k,int l,int r,int x,int y){
if (l==x&&r==y) {ptag(k); return;}
int mid=(l+r)>>1;
if (lazy[k]) ptag(k<<1),ptag(k<<1|1),lazy[k]=0;
if (y<=mid) update(k<<1,l,mid,x,y);
else if (x>mid) update(k<<1|1,mid+1,r,x,y);
else update(k<<1,l,mid,x,mid),update(k<<1|1,mid+1,r,mid+1,y);
w[k]=pup(w[k<<1],w[k<<1|1],l,mid,r);
}
rec query(int k,int l,int r,int x,int y){
if (l==x&&r==y) return w[k];
int mid=(l+r)>>1;
if (lazy[k]) ptag(k<<1),ptag(k<<1|1),lazy[k]=0;
if (y<=mid) return query(k<<1,l,mid,x,y);
else if (x>mid) return query(k<<1|1,mid+1,r,x,y);
else return pup(query(k<<1,l,mid,x,mid),query(k<<1|1,mid+1,r,mid+1,y),x,mid,y);
}
int main(){
n=iut(),Q=iut();
for (int i=1;i<=n;++i){
char ch=getchar();
while (ch!='<'&&ch!='>') ch=getchar();
if (ch=='>') a[i]=1;
}
build(1,1,n);
for (int i=1;i<=Q;++i){
int l=iut(),r=iut();
update(1,1,n,l,r);
rec t=query(1,1,n,l,r);
print(max(t.rlw,max(t.ll,t.rr))),putchar(10);
}
return 0;
}