比赛 SYOI 专题 4:分块(根号杂烩) 评测结果 AAAAAAAAAA
题目名称 糖果公园 最终得分 100
用户昵称 op_组撒头屯 运行时间 19.341 s
代码语言 C++ 内存使用 19.07 MiB
提交时间 2024-04-17 17:20:03
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
const int N=2e5+5;
int n,m,Q;
ll p[N],w[N];
int col[N];
vector<int>g[N];
int dfn[N],idfn[N],tem=0;
int anc[20][N],dep[N];
void dfs(int u,int fa){
    idfn[dfn[u]=++tem]=u;
    anc[0][u]=fa,dep[u]=dep[fa]+1;
    for (int i=0;anc[i][anc[i][u]];i++)anc[i+1][u]=anc[i][anc[i][u]];
    for (auto v:g[u])if (v!=fa)dfs(v,u);
    idfn[++tem]=u;
    return ;
}
int lca(int x,int y){
    if (dep[x]<dep[y])swap(x,y);
    for (int i=19;i>=0;i--){
        if (anc[i][x]&&dep[anc[i][x]]>=dep[y])x=anc[i][x];
        if (x==y)return x;
    }for (int i=19;i>=0;i--)if (anc[i][x]!=anc[i][y])x=anc[i][x],y=anc[i][y];
    return anc[0][x];
}

int qcnt=0,S;
struct node{
    int l,r,tim,id;
}q[N];
pii mdf[N];
ll ans[N],curans=0;

int cnt[N],vis[N];
inline void add(int x){curans+=p[col[x]]*w[++cnt[col[x]]];}
inline void del(int x){curans-=p[col[x]]*w[cnt[col[x]]--];}
inline void modify(int x){
    x=idfn[x];
    if (!vis[x])add(x);
    else del(x);
    vis[x]^=1;
}
inline void change(int x){
    int u=mdf[x].fi;
    if (vis[u])del(u);
    swap(col[u],mdf[x].se);
    if (vis[u])add(u);
}
int main(){
	freopen ("park.in","r",stdin);
	freopen ("park.out","w",stdout);
	scanf("%d%d%d",&n,&m,&Q);
	for (int i=1;i<=m;i++)scanf("%lld",&p[i]);
	for (int i=1;i<=n;i++)scanf("%lld",&w[i]);
	for (int i=1;i<n;i++){
	    int x,y;scanf("%d%d",&x,&y);
	    g[x].pb(y),g[y].pb(x);
    }
    dfs(1,0);
    for (int i=1;i<=n;i++)scanf("%d",&col[i]);
    for (int i=1,tim=0;i<=Q;i++){
        int opt,x,y;scanf("%d%d%d",&opt,&x,&y);
        if (opt){
            x=dfn[x],y=dfn[y];
            if (x>y)swap(x,y);
            q[++qcnt]={x,y,tim,qcnt};
        }
        else mdf[++tim]={x,y};
    }
    S=sqrt(2*n);
    sort(q+1,q+qcnt+1,[&](node x,node y){
        return x.l/S!=y.l/S?x.l/S<y.l/S:x.r>y.r;
    });
    
    int nowl=1,nowr=0,nowt=0;
    for (int i=1;i<=qcnt;i++){
        int l=q[i].l,r=q[i].r,t=q[i].tim;
        while(nowl>l)modify(--nowl);
        while(nowr<r)modify(++nowr);
        while(nowl<l)modify(nowl++);
        while(nowr>r)modify(nowr--);
        while(nowt<t)change(++nowt);
        while(nowt>t)change(nowt--);
        int x=idfn[l],y=idfn[r],z=lca(x,y);
        if (z!=x&&z!=y)add(z);
        if (z!=x)add(x);
        ans[q[i].id]=curans;
        if (z!=x&&z!=y)del(z);
        if (z!=x)del(x);
    }
    for (int i=1;i<=qcnt;i++)printf("%lld\n",ans[i]);
    return 0;
}