• bzoj4941: [Ynoi2016]镜子里的昆虫


    维护每个位置x的上一个相等的位置pv[x],可以把询问表示成l<=x<=r,pv[x]<l的形式,对一次修改,均摊改变O(1)个pv的取值,因此可以用平衡树预处理出pv的变化,用cdq分治处理查询。

    #include<bits/stdc++.h>
    char buf[3000007],*ptr=buf;
    const int N=100007;
    int _(){
        int x=0;
        while(*ptr<48)++ptr;
        while(*ptr>47)x=x*10+*ptr++-48;
        return x;
    }
    struct itv{
        int l;
        mutable int r,x;
        bool operator<(const itv&w)const{return l<w.l;}
    };
    typedef std::set<itv>::iterator IT;
    std::set<itv>c,cs[N*2];
    int n,m,v0[N],vs[N*2],vp=0;
    int os[N][4],pw[N*2],pv[N];
    struct P{
        int t,x,y,a;
        bool operator<(const P&w)const{return x<w.x;}
    }ps[N*10],qs[N*2],pb[N*10];
    int px[N],qx[N];
    int pp=0,qp=0,now,ans[N];
    int bit[N][2],tk=1,c0;
    void inc(int w,int a){
        if(!w)c0+=a;
        else for(;w<=n;w+=w&-w){
            bit[w][0]!=tk?bit[w][0]=tk,bit[w][1]=0:0;
            bit[w][1]+=a;
        }
    }
    int sum(int w){
        int s=c0;
        for(;w;w-=w&-w){
            s+=(bit[w][0]==tk?bit[w][1]:0);
        }
        return s;
    }
    void clr(){
        ++tk,c0=0;
    }
    void msort(P*l,P*m,P*r){
        P*bp=pb,*p1=l,*p2=m;
        while(p1!=m&&p2!=r)*bp++=*(p1->x<p2->x?p1:p2)++;
        while(p1!=m)*bp++=*p1++;
        while(p2!=r)*bp++=*p2++;
        memcpy(l,pb,(r-l)*sizeof(P));
    }
    void calc(int L,int R,int lp,int rp,int lq,int rq){
        if(L==R){
            std::sort(ps+lp,ps+rp);
            std::sort(qs+lq,qs+rq);
            return;
        }
        int M=(L+R)>>1,mp=px[M],mq=qx[M];
        calc(L,M,lp,mp,lq,mq);
        calc(M+1,R,mp,rp,mq,rq);
        if(lp<mp&&mq<rq){
            clr();
            for(int i=mq,j=lp;i<rq;++i){
                for(;j<mp&&ps[j].x<=qs[i].x;++j)inc(ps[j].y,ps[j].a);
                int z;
                ans[qs[i].t]+=z=sum(qs[i].y)*qs[i].a;
            }
        }
        msort(ps+lp,ps+mp,ps+rp);
        msort(qs+lq,qs+mq,qs+rq);
    }
    void setpv(int w,int v){
        if(pv[w]==v)return;
        ps[pp++]=(P){now,w,pv[w],-1};
        pv[w]=v;
        ps[pp++]=(P){now,w,v,1};
    }
    int getpv(int w,int x){
        IT it=cs[w].lower_bound((itv){x});
        if(it==cs[w].begin())return 0;
        --it;
        return it->r>=x?x-1:it->r;
    }
    void setq(int l,int r){
        qs[qp++]=(P){now,r,l-1,1};
        qs[qp++]=(P){now,l-1,l-1,-1};
    }
    int xs[N],xp,cms[N],cp;
    void modify(int l,int r,int x){
        IT it,it2,del;
        xp=cp=0;
        it=c.upper_bound((itv){r});--it;
        if(it->r>r){
            cs[it->x].insert((itv){r+1,it->r});
            cs[it->x].find(*it)->r=r;
            c.insert((itv){r+1,it->r,it->x});
            it->r=r;
        }
        it=c.upper_bound((itv){l});--it;
        if(it->l<l){
            cs[it->x].insert((itv){l,it->r});
            cs[it->x].find(*it)->r=l-1;
            c.insert((itv){l,it->r,it->x});
            it->r=l-1;
        }
        for(it=c.find((itv){l});it!=c.end();it2=it,++it,c.erase(it2)){
            xs[xp++]=it->l;
            if(it->l>r)break;
            cms[cp++]=it->x;
            cs[it->x].erase(*it);
        }
        c.insert((itv){l,r,x});
        cs[x].insert((itv){l,r});
        for(int i=0;i<xp;++i){
            int d=xs[i]-1;
            if(xs[i]==l)d=getpv(x,xs[i]);
            else if(xs[i]>r)d=getpv(it->x,xs[i]);
            setpv(xs[i],d);
        }
        cms[cp++]=x;
        for(int i=0;i<cp;++i){
            it=cs[cms[i]].upper_bound((itv){r});
            if(it!=cs[cms[i]].end()){
                setpv(it->l,getpv(cms[i],it->l));
            }
        }
    }
    int main(){
        fread(buf,1,sizeof(buf),stdin);
        n=_();m=_();
        for(int i=1;i<=n;++i)vs[vp++]=v0[i]=_();
        for(int i=1;i<=m;++i){
            os[i][0]=_();
            os[i][1]=_();
            os[i][2]=_();
            if(os[i][0]==1)vs[vp++]=os[i][3]=_();
        }
        std::sort(vs,vs+vp);
        vp=std::unique(vs,vs+vp)-vs;
        for(int i=1;i<=n;++i)v0[i]=std::lower_bound(vs,vs+vp,v0[i])-vs;
        for(int i=1;i<=m;++i)os[i][3]=std::lower_bound(vs,vs+vp,os[i][3])-vs;
        for(int i=1;i<=n;++i){
            cs[v0[i]].insert((itv){i,i});
            c.insert((itv){i,i,v0[i]});
            pv[i]=pw[v0[i]];
            ps[pp++]=(P){0,i,pv[i],1};
            pw[v0[i]]=i;
        }
        px[0]=pp,qx[0]=qp;
        for(int i=now=1;i<=m;++now,++i){
            if(os[i][0]==1)modify(os[i][1],os[i][2],os[i][3]);
            else setq(os[i][1],os[i][2]);
            px[i]=pp,qx[i]=qp;
        }
        calc(0,m,0,pp,0,qp);
        for(int i=1;i<=m;++i)if(os[i][0]==2)printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    转载 Spring boot中配置事务管理
    Mybatis Plus条件构造器condition动态判断优化
    【转载】 利用p6spy拦截并查看数据库执行操作
    使用P6Spy监控你的Spring boot数据库操作
    【转载】 《SpringBoot2.0 实战》系列-集成Quartz定时任务(持久化到数据库)
    baomidou的dynamic-datasource读写分离实现和加入AOP根据方法名选择库
    @EnableWebMvc 注解会让Swagger无效访问的问题
    RestTemplate发送请求并携带header信息
    Shell/Linux 将一个文件中的每两行合并成一行
    蛋白质印迹法(免疫印迹试验,Western Blot)
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7416342.html
Copyright © 2020-2023  润新知