NaCly_Fish @ 2018-12-30 00:27:37
样例都过不了,调到自闭了QAQ
用的是直接在树上暴力分块
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#define N 100003
#define reg register
using namespace std;
struct query{
int u,v,t,id;
query(int u=0,int v=0,int t=0,int id=0):u(u),v(v),t(t),id(id){}
};
struct change{
int u,last,next;
change(int u=0,int last=0,int next=0):u(u),last(last),next(next){}
};
query q[N];
change c[N];
int val[N],w[N],fa[N],depth[N],son[N],stack[N];
int sub[N],top[N],be[N],clr[N],ans[N],sum[N];
bool vis[N];
int n,m,T,tp,block,idx,res;
vector<int> adj[N];
inline void read(int &x);
void print(int x);
bool cmp(query a,query b);
void dfs1(int u,int f);
void dfs2(int u,int f);
inline int lca(int u,int v);
inline void modify(int i,int t);//单点修改
inline void update(int u);//更新节点
inline void add(int u);
inline void del(int u);
//区间添加/删除节点
void move(int u,int v);
//移动节点u至v
int main(){
int op,t,qc,u,v,p;
read(n),read(m),read(T);
block = pow(n,0.6666666);
for(reg int i=1;i<=m;++i) read(val[i]);
for(reg int i=1;i<=n;++i) read(w[i]);
for(reg int i=1;i<n;++i){
read(u),read(v);
adj[u].push_back(v);
adj[v].push_back(u);
}
for(reg int i=1;i<=n;++i){
read(clr[i]);
stack[i] = clr[i];
}
t = qc = 0;
for(reg int i=1;i<=T;++i){
read(op),read(u),read(v);
if(op==0){
c[++t] = change(u,stack[u],v);
stack[u] = v;
}else q[++qc] = query(u,v,t,i);
}
memset(stack,0,sizeof(stack));
dfs1(1,0);
dfs2(1,1);
while(tp>0) be[stack[tp--]] = idx;
sort(q+1,q+1+qc,cmp);
t = 0;
for(int i=1;i<=qc;++i){
if(t<q[i].t) modify(c[t+1].u,c[t+1].next),++t;
if(t>q[i].t) modify(c[t].u,c[t].last),--t;
if(u!=q[i].u) move(u,q[i].u);
if(v!=q[i].v) move(v,q[i].v);
p = lca(u,v); //特判lca
update(p);
ans[q[i].id] = res;
update(p);
}
for(int i=1;i<=qc;++i){
print(ans[i]);
putchar('\n');
}
return 0;
}
inline void add(int u){
++sum[u];
res += w[sum[u]]*val[u];
}
inline void del(int u){
res -= w[sum[u]]*val[u];
--sum[u];
}
inline void update(int u){
if(vis[u]) del(clr[u]),vis[u] = false;
else add(clr[u]),vis[u] = true;
}
inline void modify(int u,int t){
if(vis[u]){
del(clr[u]);
add(t);
}
clr[u] = t;
}
void move(int u,int v){
if(depth[u]<depth[v]) swap(u,v);
while(depth[u]>depth[v]){
update(u);
u = fa[u];
}
while(u!=v){
update(u),update(v);
u = fa[u],v = fa[v];
}
}
inline void read(int &x){
x = 0;
char c = getchar();
while(c<'0'||c>'9') c = getchar();
while(c>='0'&&c<='9'){
x = (x<<3)+(x<<1)+(c^48);
c = getchar();
}
}
void print(int x){
if(x>9) print(x/10);
putchar(x%10+'0');
}
void dfs1(int u,int f){
int bt = tp;
fa[u] = f;
depth[u] = depth[f]+1;
sub[u] = 1;
int v,t = -1,l = adj[u].size();
for(int i=0;i<l;++i){
v = adj[u][i];
if(v==f) continue;
dfs1(v,u);
if(tp-bt>block){
++idx;
while(tp!=bt) be[stack[tp--]] = idx;
}
sub[u] += sub[v];
if(sub[v]>t){
t = sub[v];
son[u] = v;
}
}
stack[++tp] = u;
}
void dfs2(int u,int f){
top[u] = f;
if(son[u]==0) return;
dfs2(son[u],f);
int v,l = adj[u].size();
for(int i=0;i<l;++i){
v = adj[u][i];
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
inline int lca(int u,int v){
while(top[u]!=top[v]){
if(depth[top[u]]<depth[top[v]])
swap(u,v);
u = fa[top[u]];
}
if(depth[u]<depth[v]) return u;
return v;
}
bool cmp(query a,query b){
if(be[a.u]==be[b.u]){
if(be[a.v]==be[b.v]) return a.t<b.t;
return be[a.v]<be[b.v];
}
return be[a.u]<be[b.u];
}
by NaCly_Fish @ 2019-01-02 23:37:58
话说此贴作废,已经A了(
by Pecuria @ 2019-01-13 14:54:22
@NaCly_Fish 话说你们是怎么没有tle的,怕不是我人丑常数大qwq
by NaCly_Fish @ 2019-01-13 16:52:37
@EnTaroTassadar 但是您强啊 orz