码迷,mamicode.com
首页 > 其他好文 > 详细

uoj #58【WC2013】糖果公园

时间:2017-08-16 13:14:24      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:its   ack   lca   class   ++   --   模板   sizeof   type   

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 #58【WC2013】糖果公园

标签:its   ack   lca   class   ++   --   模板   sizeof   type   

原文地址:http://www.cnblogs.com/ccz181078/p/7372754.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!