AC[1,3],TLE[4,10]。
正确性应该没有问题,写了对拍,小数据拍不出来错误。
对于第四个点,下载下来在本地测大约10s能跑完,推测是因为常数过大寄了(应该没有假吧……)
调了好久,想不明白哪里有问题,有没有dalao可以帮我看看!
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 200005;
inline int read(){
int s = 0;char ch = getchar();
while(ch<'0'||ch>'9')ch = getchar();
while(ch>='0'&&ch<='9'){s = (s<<1)+(s<<3)+ch-'0';ch = getchar();}
return s;
}
int n,m,q,cnt[N],ect = 1,hd[N],ck[N],lid[N],khi[N],fa[N],dep[N],kct,s;
int topf[N],sz[N],son[N];
struct E{
int v,nt;
}e[2*N];
void add(int u,int v){
e[ect].v = v;
e[ect].nt = hd[u];
hd[u] = ect++;
}
bool vis[N];
//树剖的第一个dfs,同时求括号序
void dfs(int p,int fn){
fa[p] = fn;
dep[p] = dep[fn]+1;
sz[p] = 1;
khi[++kct] = p;
lid[p] = kct;
for(int i = hd[p];i;i = e[i].nt){
if(e[i].v==fn)continue;
dfs(e[i].v,p);
sz[p]+=sz[e[i].v];
if(sz[son[p]]<sz[e[i].v])son[p] = e[i].v;
}
khi[++kct] = p;
}
//树剖的dfs2
void dfs2(int p,int ntop){
topf[p] = ntop;
if(!son[p])return;
dfs2(son[p],ntop);
for(int i = hd[p];i;i = e[i].nt){
if(e[i].v==fa[p]||e[i].v==son[p])continue;
dfs2(e[i].v,e[i].v);
}
}
ll v[N],w[N],oa[N];
struct Q{
int u,v,id,qid,l,r;
}qr[N];
struct C{
int p,k;
}cg[N];
//莫队排序的cmp(不保证正确性的奇偶排序优化)
bool cmp(Q a,Q b){
if(a.l/s==b.l/s){
if(a.r/s==b.r/s){
if((a.r/s)&1)return a.id>b.id;
return a.id<b.id;
}
if((a.l/s)&1)return a.r>b.r;
return a.r<b.r;
}
return a.l<b.l;
}
ll ans;
int l = 1,r = 0,nq = 0;
//下面传的是树上节点的编号
void del(int p){
p = ck[p];
ans-=w[cnt[p]--]*v[p];
}
void add(int p){
p = ck[p];
ans+=w[++cnt[p]]*v[p];
}
void Cg(int p){
p = khi[p];
if(vis[p])del(p);
else add(p);
vis[p] = !vis[p];
}
void change(int cid){
int p = cg[cid].p;
if(vis[p]){
del(p);
swap(ck[p],cg[cid].k);
add(p);
}else{
swap(ck[p],cg[cid].k);
}
}
//树剖lca
int lca(int u,int v){
while(topf[u]!=topf[v]){
if(dep[topf[u]]<dep[topf[v]])swap(u,v);
u = fa[topf[u]];
}
if(dep[u]<dep[v])return u;
return v;
}
int main(){
// freopen("P4074_4.in","r",stdin);
// freopen("dt.out","r",stdin);
// freopen("zj.out","w",stdout);
n = read();m = read();q = read();
for(int i = 1;i<=m;i++)v[i] = read();
for(int i = 1;i<=n;i++)w[i] = read();
int uu,vv;
for(int i = 1;i<n;i++){
uu = read();vv = read();
add(uu,vv);add(vv,uu);
}
dfs(1,0);dfs2(1,1);
for(int i = 1;i<=n;i++)ck[i] = read();
int cgct = 0,qrct = 0,op;
for(int i = 1;i<=q;i++){
op = read();
if(op==0){
cg[++cgct].p = read();
cg[cgct].k = read();
continue;
}
qr[++qrct].u = uu = read();
qr[qrct].v = vv = read();
if(lid[uu]>lid[vv]){
swap(qr[qrct].u,qr[qrct].v);
swap(uu,vv);
}
qr[qrct].id = qrct;
qr[qrct].qid = cgct;
qr[qrct].l = lid[uu];
qr[qrct].r = lid[vv];
}
s = pow(n,2.0/3);
q = qrct;
int qrq,qrl,qrr;
for(int i = 1;i<=q;i++){
qrl = qr[i].l;qrr = qr[i].r;qrq = qr[i].qid;
while(nq<qrq)change(++nq);
while(nq>qrq)change(nq--);
while(r<qrr)Cg(++r);
while(l>qrl)Cg(--l);
while(r>qrr)Cg(r--);
while(l<qrl)Cg(l++);
int nl = lca(qr[i].u,qr[i].v);
if(nl!=qr[i].u&&nl!=qr[i].v)add(nl);
if(qr[i].u!=nl)add(qr[i].u);
oa[qr[i].id] = ans;
if(nl!=qr[i].u&&nl!=qr[i].v)del(nl);
if(qr[i].u!=nl)del(qr[i].u);
}
for(int i = 1;i<=q;i++){
printf("%lld\n",oa[i]);
}
return 0;
}