P5445 [APIO2019]路灯(树套树)

P5445 [APIO2019]路灯

转化为平面上的坐标(x,y)set维护连续区间.

用树套树维护矩阵加法,单点查询。

注意维护矩阵差分的时候,

$(x,y,v)$是对$(x,y)(n+1,n+1)$的矩阵做出贡献

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#define ri register int
using namespace std;
int read(){
    char c=getchar(); ri x=0;
    while(c<'0'||c>'9') c=getchar();
    while('0'<=c&&c<='9') x=x*10+c-48,c=getchar();
    return x;
}
#define N 600005
#define W 20000005
struct E{
    int l,r;
    E(int A,int B):l(A),r(B){}
    bool operator < (const E &G) const{return r<G.r;}
};set<E> g;
set<E>::iterator it;
int n,T,a[N]; char opt[9],cc[N];
int cnt,rt[N],lc[W],rc[W],s[W];
#define mid (l+r)/2
void Ins1(int &o,int l,int r,int x,int v){
    if(!o)o=++cnt; s[o]+=v;
    if(l==r) return; 
    if(x<=mid) Ins1(lc[o],l,mid,x,v);
    else Ins1(rc[o],mid+1,r,x,v);
}
int Ask1(int o,int l,int r,int x1,int x2){
    if(!o||x2<l||r<x1) return 0;
    if(x1<=l&&r<=x2) return s[o];
    return Ask1(lc[o],l,mid,x1,x2)+Ask1(rc[o],mid+1,r,x1,x2);
}
void Ins2(int x,int y,int v){for(;x<=n+1;x+=x&-x)Ins1(rt[x],1,n+1,y,v);}
int Ask2(int x,int y){int re=0; for(;x;x-=x&-x)re+=Ask1(rt[x],1,n+1,1,y); return re;}
inline void Add(int x1,int y1,int x2,int y2,int v){//注意修改标记是对右上的查询产生贡献,并不是平移区间
    Ins2(x1,y1,v),Ins2(x1,y2+1,-v),Ins2(x2+1,y1,-v),Ins2(x2+1,y2+1,v);
}
int main(){
    n=read()+1; T=read(); scanf("%s",cc+1);
    for(ri i=1;i<=n;++i) g.insert(E(i,i));
    int x,y,pl,pr,ql,qr;
    for(ri i=1;i<n;++i) if((a[i]=cc[i]-48)){
        it=g.lower_bound(E(0,i+1)); --it; pl=(*it).l;
        g.erase(it); g.erase(E(i+1,i+1)); g.insert(E(pl,i+1));
    }
    for(it=g.begin();it!=g.end();++it) Add((*it).l,(*it).l,(*it).r,(*it).r,T);
    for(ri t=1;t<=T;++t){
        scanf("%s",opt);
        if(opt[0]=='q'){
            x=read(); y=read();
            pl=(*(g.lower_bound(E(0,x)))).l;
            ql=(*(g.lower_bound(E(0,y)))).l;
            printf("%d
",Ask2(x,y)-(T-t)*(pl==ql));
        }else{
            x=read();
            if(a[x]){
                it=g.lower_bound(E(0,x));
                pl=(*it).l,pr=x; ql=x+1,qr=(*it).r;
                Add(pl,ql,pr,qr,t-T);
                g.erase(it); g.insert(E(pl,pr)); g.insert(E(ql,qr));
            }else{
                it=g.lower_bound(E(0,x));
                pl=(*it).l,pr=x; ++it; ql=x+1,qr=(*it).r;
                Add(pl,ql,pr,qr,T-t);
                g.erase(E(pl,pr)); g.erase(E(ql,qr)); g.insert(E(pl,qr));
            }a[x]^=1;
        }
    }return 0;
}
原文地址:https://www.cnblogs.com/kafuuchino/p/11391532.html