uoj #58WC2013糖果公园

Posted ccz181078

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uoj #58WC2013糖果公园相关的知识,希望对你有一定的参考价值。

http://uoj.ac/problem/58

树上带修莫队模板题

#include<bits/stdc++.h>
const int N=100007;
typedef long long i64;
char buf[N*100],*ptr=buf-1,ob[N*25],*op=ob;
int _(){
    int x=0;
    while(*ptr<48)++ptr;
    while(*ptr>47)x=x*10+*ptr++-48;
    return x;
}
void pr(i64 x){
    int ss[25],sp=0;
    do ss[++sp]=x%10+48;while(x/=10);
    while(sp)*op++=ss[sp--];
    *op++=10;
}
void maxs(int&a,int b){if(a<b)a=b;}
int n,m,q;
std::vector<int>e[N];
int v1[N],v2[N],c[N];
int tk=0;
int os[N][3];
int X=1,Y=1,Z=0,in[N];
int ts[N],dep[N],fa[N],sz[N],top[N],son[N],md[N],id[N],idp=0,D=1;
i64 ans=0;
inline void del(int x){ans-=i64(v1[x])*v2[ts[x]--];}
inline void ins(int x){ans+=i64(v1[x])*v2[++ts[x]];}
void f2(int w){
    id[w]=idp;
    for(int i=0;i<e[w].size();++i){
        int u=e[w][i];
        if(u!=fa[w]&&!id[u])f2(u);
    }
}
void f3(int w,int tp){
    top[w]=tp;
    if(son[w])f3(son[w],tp);
    for(int i=0;i<e[w].size();++i){
        int u=e[w][i];
        if(u!=fa[w]&&u!=son[w])f3(u,u);
    }
}
void f1(int w,int pa){
    dep[w]=dep[fa[w]=pa]+1;
    sz[w]=1;
    for(int i=0;i<e[w].size();++i){
        int u=e[w][i];
        if(u!=pa){
            f1(u,w);
            sz[w]+=sz[u];
            if(sz[u]>sz[son[w]])son[w]=u;
            if(!id[u])maxs(md[w],md[u]+1);
        }
    }
    if(w==1||md[w]==D)++idp,f2(w);
}
int lca(int x,int y){
    int a=top[x],b=top[y];
    while(a!=b){
        if(dep[a]>dep[b])x=fa[a],a=top[x];
        else y=fa[b],b=top[y];
    }
    return dep[x]<dep[y]?x:y;
}
i64 as[N];
struct Q{
    int x,y,z,ID;
    bool operator<(const Q&w)const{
        if(id[x]!=id[w.x])return id[x]<id[w.x];
        if(id[y]!=id[w.y])return (id[y]<id[w.y])^(id[x]&1);
        return z<w.z;
    }
    void mov(int&w0,int b){
        int a=w0;w0=b;
        int g=lca(a,b);
        for(;a!=g;a=fa[a])(in[a]^=1)?ins(c[a]):del(c[a]);
        for(;b!=g;b=fa[b])(in[b]^=1)?ins(c[b]):del(c[b]);
    }
    void cal(){
        int w;
        while(Z<z){
            ++Z;
            if(in[w=os[Z][0]]){
                del(c[w]);
                ins(c[w]=os[Z][2]);
            }
            c[w]=os[Z][2];
        }
        while(Z>z){
            if(in[w=os[Z][0]]){
                del(c[w]);
                ins(os[Z][1]);
            }
            c[w]=os[Z][1];
            --Z;
        }
        mov(X,x);
        mov(Y,y);
        int g=lca(x,y);
        ins(c[g]);
        as[ID]=ans;
        del(c[g]);
    }
}qs[N];
int qp=0;
int main(){
    fread(buf,1,sizeof(buf),stdin);
    n=_();m=_();q=_();
    for(int i=1;i<=m;++i)v1[i]=_();
    for(int i=1;i<=n;++i)v2[i]=_();
    for(int i=1,a,b;i<n;++i){
        a=_(),b=_();
        e[a].push_back(b);
        e[b].push_back(a);
    }
    for(int i=1;i<=n;++i)c[i]=_();
    for(int i=0;i<q;++i){
        int o=_(),x=_(),y=_();
        if(o)qs[qp]=(Q){x,y,tk,qp},++qp;
        else{
            ++tk;
            os[tk][0]=x;
            os[tk][1]=c[x];
            os[tk][2]=c[x]=y;
        }
    }
    if(tk<=5)D=sqrt(n)+1;
    else D=pow(n,0.67)+1;
    f1(1,0);f3(1,1);
    std::sort(qs,qs+qp);
    X=Y=1,Z=tk;
    for(int i=0;i<qp;++i)qs[i].cal();
    for(int i=0;i<qp;++i)pr(as[i]);
    fwrite(ob,1,op-ob,stdout);
    return 0;
}

 

以上是关于uoj #58WC2013糖果公园的主要内容,如果未能解决你的问题,请参考以下文章

uoj #58WC2013糖果公园

uoj58 WC2013—糖果公园

BZOJ3052 & UOJ58:WC2013糖果公园——题解

●UOJ58 [WC2013]糖果公园

UOJ#58. WC2013糖果公园

[UOJ #58][WC2013]糖果公园(树上带修改莫队)