zoukankan      html  css  js  c++  java
  • 【知识点】莫队

    莫队:

    离线后通过对询问合理排序使得复杂度降低一个$sqrt{n}$。(本身并不需要用块维护东西)

    一般情况下分块大小为$sqrt{n}$,以左端点所在块为第一关键字,右端点为第二关键字排序。

    然后依次暴力处理询问即可。

    带修莫队:

    一般情况下分块大小为$n^{frac{2}{3}}$,以左端点所在块为第一关键字,右端点所在块为第二关键字,该询问之前的修改数为第三关键字排序。

    然后依次暴力处理询问和修改即可。

    树上莫队:

    一般情况下用欧拉序把树转成括号序列。(每个点第一次dfs到时加入,最后一次dfs回溯时加入)

    然后当成序列做,把加入/删除改成xor即可。

    代码(WC2013糖果公园):

    #include<bits/stdc++.h>
    #define maxn 500005
    #define maxm 500005
    #define inf 0x7fffffff
    #define ll long long
    #define rint register ll
    #define debug(x) cerr<<#x<<": "<<x<<endl
    #define fgx cerr<<"--------------"<<endl
    #define dgx cerr<<"=============="<<endl
    
    using namespace std;
    ll V[maxn],W[maxn],A[maxn],B[maxn],C[maxn];
    ll nxt[maxn<<1],to[maxn<<1],hd[maxn];
    ll F[maxn][20],tC[maxn],E[maxn],tot;
    ll dep[maxn],st[maxn],ed[maxn],totu;
    ll vis[maxn],num[maxn],ans,cnt,siz;
    struct node{ll l,r,val,id,res;}Q[maxn],U[maxn];
    
    inline ll read(){
        ll x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    
    inline void addedge(ll u,ll v){
        to[++cnt]=v,nxt[cnt]=hd[u],hd[u]=cnt;
        to[++cnt]=u,nxt[cnt]=hd[v],hd[v]=cnt;
    }
    
    inline void dfs(ll u,ll fa){
        E[++E[0]]=u,st[u]=E[0];
        dep[u]=dep[fa]+1,F[u][0]=fa;
        for(ll i=1;i<20;i++) F[u][i]=F[F[u][i-1]][i-1];
        for(ll i=hd[u];i;i=nxt[i]){
            ll v=to[i];
            if(v!=fa) dfs(v,u); 
        }
        E[++E[0]]=u,ed[u]=E[0];
    }
    
    inline bool cmp(node a,node b){
        if(a.l/siz==b.l/siz && a.r/siz==b.r/siz) return a.val<b.val;
        else if(a.l/siz==b.l/siz) return a.r/siz<b.r/siz;
        else return a.l/siz<b.l/siz;
    }
    inline bool cmp1(node a,node b){return a.id<b.id;}
    
    inline ll lca(ll x,ll y){
        if(dep[x]>dep[y]) swap(x,y);
        for(ll i=19;i>=0;i--)
            if(dep[F[y][i]]>=dep[x])
                y=F[y][i];
        if(x==y) return x;
        for(ll i=19;i>=0;i--)
            if(F[x][i]!=F[y][i])
                x=F[x][i],y=F[y][i];
        return F[x][0];
    }
    
    inline void upd(ll u){
        vis[u]^=1;
        if(vis[u]) ans+=W[++num[C[u]]]*V[C[u]];
        else ans-=W[num[C[u]]--]*V[C[u]];
    }
    
    int main(){
        ll n=read(),m=read(),q=read();
        for(ll i=1;i<=m;i++) V[i]=read(); 
        for(ll i=1;i<=n;i++) W[i]=read();
        for(ll i=1;i<=n-1;i++){
            ll u=read(),v=read();
            addedge(u,v);
        }
        for(ll i=1;i<=n;i++) tC[i]=C[i]=read();
        for(ll i=1;i<=q;i++){
            ll typ=read(),x=read(),y=read();
            if(typ==0) U[++totu].val=x,U[totu].l=tC[x],U[totu].r=y,tC[x]=y;
            else Q[++tot].l=x,Q[tot].r=y,Q[tot].val=totu,Q[tot].id=tot,Q[tot].res=0; 
        }    
        dfs(1,0),siz=pow(2.0*n,2.0/3.0);
        for(ll i=1;i<=tot;i++){
            ll x=Q[i].l,y=Q[i].r;
            if(dep[x]>dep[y]) swap(x,y); 
            if(lca(x,y)==x) Q[i].l=st[x],Q[i].r=st[y];
            else{
                if(st[x]>st[y]) swap(x,y);
                Q[i].l=ed[x],Q[i].r=st[y];
            }
        }
        sort(Q+1,Q+1+tot,cmp);
        for(ll i=1;i<=tot;i++){
            ll l=Q[i-1].l,r=Q[i-1].r,p=Q[i-1].val;
            ll f1=lca(E[Q[i-1].l],E[Q[i-1].r]);
            if(f1!=E[Q[i-1].l]) upd(f1);
            while(p<Q[i].val){ 
                ll j=++p; 
                if(l<=st[U[j].val] && r>=st[U[j].val] && r<ed[U[j].val]) upd(U[j].val);
                if(l<=ed[U[j].val] && r>=ed[U[j].val] && l>st[U[j].val]) upd(U[j].val);
                C[U[j].val]=U[j].r;
                if(l<=st[U[j].val] && r>=st[U[j].val] && r<ed[U[j].val]) upd(U[j].val);
                if(l<=ed[U[j].val] && r>=ed[U[j].val] && l>st[U[j].val]) upd(U[j].val);
            }
            while(p>Q[i].val){
                ll j=p--;
                if(l<=st[U[j].val] && r>=st[U[j].val] && r<ed[U[j].val]) upd(U[j].val);
                if(l<=ed[U[j].val] && r>=ed[U[j].val] && l>st[U[j].val]) upd(U[j].val);
                C[U[j].val]=U[j].l;
                if(l<=st[U[j].val] && r>=st[U[j].val] && r<ed[U[j].val]) upd(U[j].val);
                if(l<=ed[U[j].val] && r>=ed[U[j].val] && l>st[U[j].val]) upd(U[j].val);
            }
            while(l<Q[i].l) upd(E[l++]);
            while(l>Q[i].l) upd(E[--l]);
            while(r<Q[i].r) upd(E[++r]);
            while(r>Q[i].r) upd(E[r--]);
            ll f2=lca(E[Q[i].l],E[Q[i].r]);
            if(f2!=E[Q[i].l]) upd(f2);
            Q[i].res=ans;
        }
        sort(Q+1,Q+1+tot,cmp1);
        for(ll i=1;i<=tot;i++)
            printf("%lld
    ",Q[i].res);
        return 0;
    }
    糖果公园
  • 相关阅读:
    [na][dhcp]华为DHCP-重要
    [na]win PPTP场景与搭建
    [na]锐起无盘机并发部署多台windows
    [na]wireshark抓包排错-tcp.flags.reset
    [svc]mousedos网络批量部署xp
    [na]诺顿ghost磁盘对刻(备份系统分区或数据分区)
    [na]代理arp导致的问题(路由卷)
    [na]pc加入域认证细节
    【VS开发】【智能语音处理】VS中声音的采集实现
    【VS开发】【智能语音处理】MATLAB 与 音频处理 相关内容摘记
  • 原文地址:https://www.cnblogs.com/YSFAC/p/13064735.html
Copyright © 2011-2022 走看看