比赛 |
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;
}