题面

中文题面,难得解释了

BZOJ传送门

Luogu传送门

分析

树上带修莫队板子题。。。

开始没给分块大小赋初值T了好一会。。。

CODE

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template<typename T>inline void read(T &num) {
char ch; while((ch=getchar())<'0'||ch>'9');
for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
}
const int MAXN = 100005;
int Block, n, m, q, V[MAXN], W[MAXN], a[MAXN], bel[MAXN], la[MAXN], val[MAXN];
LL ans[MAXN], Ans; bool vis[MAXN];
struct Change {
int i, u, v;
}C[MAXN];
struct Query {
int u, v, t, id;
inline bool operator <(const Query &o)const {
return bel[u] == bel[o.u] ? (bel[v] == bel[o.v] ? t < o.t : bel[v] < bel[o.v]) : bel[u] < bel[o.u];
}
}Q[MAXN];
int fir[MAXN], to[MAXN<<1], nxt[MAXN<<1], cnt;
inline void add(int x, int y) { to[++cnt] = y; nxt[cnt] = fir[x]; fir[x] = cnt; }
int f[MAXN][17], dep[MAXN], dfn[MAXN], tmr, stk[MAXN], tot, top;
void dfs(int u, int ff) {
int bot = top; dfn[u] = ++tmr;
dep[u] = dep[f[u][0]=ff] + 1;
for(int i = fir[u]; i; i = nxt[i])
if(to[i] != ff) {
dfs(to[i], u);
if(top-bot > Block) {
++tot; while(top > bot) bel[stk[top--]] = tot;
}
}
stk[++top] = u;
}
inline void Pre() {
for(int j = 1; j < 17; ++j)
for(int i = 1; i <= n; ++i)
f[i][j] = f[f[i][j-1]][j-1];
}
inline int lca(int u, int v) {
if(dep[v] > dep[u]) swap(u, v);
for(int i = 0; i < 17; ++i)
if((dep[u]-dep[v])&(1<<i)) u = f[u][i];
if(u == v) return u;
for(int i = 16; ~i; --i)
if(f[u][i] != f[v][i]) u = f[u][i], v = f[v][i];
return f[u][0];
}
inline void upd(int i) {
if(!vis[i]) {
vis[i] = 1;
Ans += 1ll * V[a[i]] * W[++val[a[i]]];
}
else {
vis[i] = 0;
Ans -= 1ll * V[a[i]] * W[val[a[i]]--];
}
}
inline void mdf(int i, int col) {
if(!vis[i]) { a[i] = col; return; }
upd(i), a[i] = col, upd(i);
} inline void rev(int u, int v) {
while(u != v) {
if(dep[v] > dep[u]) swap(u, v);
upd(u), u = f[u][0];
}
}
int main () {
read(n), read(m), read(q); Block = pow(n, 0.67);
for(int i = 1; i <= m; ++i) read(V[i]);
for(int i = 1; i <= n; ++i) read(W[i]);
for(int i = 1, x, y; i < n; ++i) read(x), read(y), add(x, y), add(y, x);
for(int i = 1; i <= n; ++i) read(a[i]), la[i] = a[i];
dfs(1, 0); Pre();
if(top) ++tot; while(top) bel[stk[top--]] = tot;
int cntc = 0, cntq = 0, opt, x, y;
while(q--) {
read(opt), read(x), read(y);
if(!opt) C[++cntc] = (Change){ x, la[x], y }, la[x] = y;
else {
if(dfn[x] > dfn[y]) swap(x, y);
Q[++cntq] = (Query){ x, y, cntc, cntq };
}
}
sort(Q + 1, Q + cntq + 1);
int TIMES = 0, LCA = lca(Q[1].u, Q[1].v);
while(TIMES < Q[1].t) ++TIMES, mdf(C[TIMES].i, C[TIMES].v);
rev(Q[1].u, Q[1].v);
upd(LCA), ans[Q[1].id] = Ans, upd(LCA);
for(int i = 2; i <= cntq; ++i) {
while(TIMES < Q[i].t) ++TIMES, mdf(C[TIMES].i, C[TIMES].v);
while(TIMES > Q[i].t) mdf(C[TIMES].i, C[TIMES].u), --TIMES;
rev(Q[i-1].u, Q[i].u), rev(Q[i-1].v, Q[i].v), LCA = lca(Q[i].u, Q[i].v);
upd(LCA), ans[Q[i].id] = Ans, upd(LCA);
}
for(int i = 1; i <= cntq; ++i)
printf("%lld\n", ans[i]);
}

最新文章

  1. SharePoint Online 申请试用链接地址
  2. IOS的Crash情况在Crashlytics平台上统计解决方案的一点遗憾(截止到2015年6月14日)
  3. arm64 boot
  4. C#中汉诺塔问题的递归解法
  5. Python学习笔记10—几个名词概念
  6. python03函数、递归
  7. android 检测工具: drozer
  8. 使用Yeoman搭建 AngularJS 应用 (1) —— 介绍
  9. APP评价(星星点赞)很简单
  10. CF卡技术详解——笔记
  11. 【优先队列】-HDU4546比赛难度
  12. display flex 和a标签不行
  13. php sprintf函数
  14. 十条最有效的PCB设计黄金法则
  15. 谁说深入浅出虚拟机难?现在我让他通俗易懂(JVM)
  16. const命令,全局变量的属性,变量的解构赋值
  17. docker中安装ps命令
  18. H5获取原生传过来的值
  19. java0618
  20. 【mysql】逗号分割字段的行列转换

热门文章

  1. malloc/free和new/delete详解与应用
  2. STM32固件库模板下载以及固件库学习方法
  3. css 样式合集
  4. SAS学习笔记9 利用SAS绘制地图
  5. asp.net core-2.在vs2017中创建asp.net core应用程序
  6. CentOS 7.X 静默安装Oracle 12C数据库
  7. POJ2729 Robocode(离散化与模拟-----提醒曾经爱玩游戏的自己没做出这个
  8. 使用zrender.js绘制体温单(1)
  9. ajax:用于创建快速动态网页的技术
  10. Java 面向对象(五)抽象