zoukankan      html  css  js  c++  java
  • [WC2013] 糖果公园

    link

    $solution:$

    树上莫队模板题,树上莫队计算贡献后是除去 $u,v$ 的 $lca$ 的,简单用前缀和维护即可。

    因为是带修莫队,块大小为 $n^{frac{2}{3}}$ 时时间复杂度最小,时间复杂度 $O(n^{frac{5}{3}})$ 。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #define LL long long
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=100001;
    struct node{
        int u,v,nex;
    }x[MAXN<<1];
    int cnt,head[MAXN];
    LL S[MAXN];
    void add(int u,int v){
        x[cnt].u=u,x[cnt].v=v,x[cnt].nex=head[u],head[u]=cnt++;
    }
    int n,m,q,sta[MAXN],blo,bl[MAXN],tot,fa[MAXN][21],dep[MAXN],col[MAXN];
    LL w[MAXN];
    inline void dfs(int u,int fath){
        int now=sta[0];
        fa[u][0]=fath,dep[u]=dep[fath]+1;
        for(int i=1;(1<<i)<=dep[u];i++) fa[u][i]=fa[fa[u][i-1]][i-1];
        for(int i=head[u];i!=-1;i=x[i].nex){
            if(x[i].v==fath) continue;
            dfs(x[i].v,u);
            if(sta[0]-now>=blo){
                tot++;
                while(sta[0]!=now) bl[sta[sta[0]]]=tot,sta[0]--; 
            }
        }sta[++sta[0]]=u;return;
    }
    inline int lca(int u,int v){
        if(dep[u]<dep[v]) swap(u,v);
        for(int i=18;i>=0;i--) if(dep[u]-(1<<i)>=dep[v]) u=fa[u][i];
        if(u==v) return u;
        for(int i=18;i>=0;i--){
            if(fa[u][i]==fa[v][i]) continue;
            u=fa[u][i],v=fa[v][i];
        }return fa[u][0];
    }
    int Col[MAXN];
    struct Query{
        int x,y,T,idx,idy,id;
        LL ans;
    }query[MAXN];
    struct Change{
        int x,now,las;
    }change[MAXN];
    bool cmp(Query x1,Query x2){
        if(x1.idx==x2.idx){
            if(x1.idy==x2.idy) return x1.T<x2.T;
            return x1.idy<x2.idy;
        }return x1.idx<x2.idx;
    }
    bool cmp1(Query x1,Query x2){
        return x1.id<x2.id;
    }
    int totq,totc,vis[MAXN];
    LL Ans,Cnt[MAXN];
    inline void Add(int u){
        Ans-=S[Cnt[col[u]]]*w[col[u]];
        Cnt[col[u]]++;
        Ans+=S[Cnt[col[u]]]*w[col[u]];return;
    }
    inline void del(int u){
        Ans-=S[Cnt[col[u]]]*w[col[u]];
        Cnt[col[u]]--;
        Ans+=S[Cnt[col[u]]]*w[col[u]];return;
    }
    inline void Run(int u){
        if(vis[u]){del(u),vis[u]=0;return;}
        else{Add(u);vis[u]=1;return;}
    }
    inline void Modify(int u,int w){
        if(vis[u]){
            del(u);
            col[u]=w;
            Add(u);
        }
        col[u]=w;return;
    }
    inline void move(int u,int v){
        if(dep[u]<dep[v]) swap(u,v);
        while(dep[u]>dep[v]) Run(u),u=fa[u][0];
        while(u!=v) Run(u),Run(v),u=fa[u][0],v=fa[v][0];
        return;
    }
    inline void solve(){
        int u=1,v=1,T=0;
        for(register int i=1;i<=totq;i++){
            while(T<query[i].T) Modify(change[T+1].x,change[T+1].now),T++;
            while(T>query[i].T) Modify(change[T].x,change[T].las),T--;
            
            move(u,query[i].x),u=query[i].x;
            move(v,query[i].y),v=query[i].y;
            int Lca=lca(u,v);
            Run(Lca),query[i].ans=Ans,Run(Lca);
        }return;
    }
    signed main(){
    //    freopen("1.in","r",stdin);
        memset(head,-1,sizeof(head));
        n=read(),m=read(),q=read();blo=pow(n,0.45);
        for(register int i=1;i<=m;i++) w[i]=read();
        for(register int i=1;i<=n;i++) S[i]=S[i-1]+read();
        for(register int i=1;i<n;i++){
            int u=read(),v=read();
            add(u,v),add(v,u);
        }
        dfs(1,0);
        while(sta[0]) bl[sta[sta[0]]]=tot,sta[0]--;
        for(register int i=1;i<=n;i++) Col[i]=col[i]=read();
        while(q--){
            int opt=read();
            if(opt==1){
                int x=read(),y=read();
                ++totq;
                query[totq].x=x,query[totq].y=y,query[totq].T=totc,query[totq].idx=bl[x],query[totq].idy=bl[y];
                query[totq].id=totq;
            }else{
                ++totc;
                int x=read(),co=read();
                change[totc].x=x,change[totc].las=Col[x],change[totc].now=Col[x]=co;
            }
        }
        sort(query+1,query+totq+1,cmp);
        solve();
        sort(query+1,query+totq+1,cmp1);
        for(register int i=1;i<=totq;i++) printf("%lld
    ",query[i].ans);return 0;
    }
    View Code
  • 相关阅读:
    (转)CortexM3 (NXP LPC1788)之启动代码分析
    (转)CortexM3 (NXP LPC1788)之RTC
    (转)CortexM3 (NXP LPC1788)之外部中断操作
    (原创)TCP/IP学习笔记之ARP(地址解析协议)
    (原创)CheckTool:CRC校验、累加和校验、异或和校验专业校验工具V1.0
    (转)CortexM3 (NXP LPC1788)之SysTick系统节拍定时器
    (转)CortexM3 (NXP LPC1788)之UART用法
    工具 MyEclipse8.5注册码
    Delphi – UtWinHttp_API.pas From winhttp.h
    Delphi – TCanvas.CopyRect方法中参数CopyMode的意义
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/11260322.html
Copyright © 2011-2022 走看看