#线段树#CF1371F Raging Thunder

洛谷传送门
CF1371F


分析

其实掉出区间边界或洞内就算消失,最终球只会掉到最左侧的 <,中间的 ><,和最右侧的 >

在线段树上维护左右边界上最长的<,>,<>,><和区间内最长的<>,><即可


代码

#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;
}
posted @ 2024-06-05 16:56  lemondinosaur  阅读(1)  评论(0编辑  收藏  举报