题意:

一棵树,修改一个点的颜色,询问两点路径上每种颜色的权值$val[c]$*出现次数的权值$cou[w[c]]$的和


sro VFK

树上莫队

按照王室联邦的方法分块,块的大小直径个数有保证,并不需要连通

和带修改莫队一样按照$(pos[u],pos[v],tim)$排序

维护$u,v,cur$三个点,以及每个节点的访问状态$vis[]$,每种颜色出现次数$cou[]$,当前答案$now$

如何移动?

时间移动和序列上一样

$u,v$移动到$u,v'$

$Path(u,v)=Path(u,root) \oplus Path(v,root) \oplus lca(u,v)$

先不管$lca$,令$T(u,v)=Path(u,root) \oplus Path(v,root)$

$T(u,v')=Path(u,root) \oplus Path(v',root)$

经计算$T(u,v')=T(u,v) \oplus T(v,v')$

画一下图很好理解

所以移动的时候我们只要更新$v$到$v'$路径上除去$lca$的所有点就可以了,最后对于每个询问额外把$lca(u,v)$加上

分块大小貌似稍小一点比较好

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e5+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n,k,Q,a[N],t[N],op,x,y, val[N];
ll w[N]; struct edge{int v,ne;} e[N<<];
int cnt,h[N];
inline void ins(int u,int v){
e[++cnt]=(edge){v,h[u]}; h[u]=cnt;
e[++cnt]=(edge){u,h[v]}; h[v]=cnt;
}
int block,m,pos[N];
int st[N],top;
void dfs(int u,int fa){
int bot=top;
for(int i=h[u];i;i=e[i].ne) if(e[i].v!=fa){
dfs(e[i].v, u);
if(top-bot>=block){
m++;
while(top!=bot) pos[st[top--]]=m;
}
}
st[++top]=u;
} int fa[N][], deep[N];
void dfs(int u){
for(int i=; (<<i)<=deep[u]; i++)
fa[u][i]=fa[ fa[u][i-] ][i-];
for(int i=h[u];i;i=e[i].ne)
if(e[i].v!=fa[u][]){
deep[ e[i].v ]=deep[u]+;
fa[ e[i].v ][]=u;
dfs(e[i].v);
}
}
inline int lca(int x,int y){
if(deep[x]<deep[y]) swap(x, y);
int bin=deep[x]-deep[y];
for(int i=;i<;i++) if((<<i)&bin) x=fa[x][i];
for(int i=;i>=;i--)
if(fa[x][i]!=fa[y][i]) x=fa[x][i], y=fa[y][i];
return x==y ? x : fa[x][];
} struct cmeow{int u,next,last;} cq[N];
struct meow{
int u,v,tim,id;
bool operator <(const meow &a) const {
return pos[u]==pos[a.u] ? (pos[v]==pos[a.v] ? tim<a.tim : pos[v]<pos[a.v]) : pos[u]<pos[a.u];
}
}q[N];
int p,tim,u,v,cur; ll now,ans[N];
int vis[N], cou[N];
inline void cha(int u,int d){
int &c=a[u];
if(vis[u]){
now-= w[cou[c]] * val[c]; now-= w[cou[d]] * val[d];
cou[c]--; cou[d]++;
now+= w[cou[c]] * val[c]; now+= w[cou[d]] * val[d];
}
c=d;
}
inline void Xor(int u){
int c=a[u];
now-= w[cou[c]] * val[c];
vis[u] ? cou[c]-- : cou[c]++; vis[u]^=;
now+= w[cou[c]] * val[c];
}
void move(int x,int y){
if(deep[x]<deep[y]) swap(x, y);
while(deep[x]>deep[y]) Xor(x), x=fa[x][];// printf("%d %lld\n",x,now);
while(x!=y) Xor(x), Xor(y), x=fa[x][], y=fa[y][];
}
void modui(){
u=; v=;
for(int i=;i<=p;i++){
while(cur<q[i].tim) cur++, cha(cq[cur].u, cq[cur].next);
while(cur>q[i].tim) cha(cq[cur].u, cq[cur].last), cur--;
if(u!=q[i].u) move(u, q[i].u), u=q[i].u;
if(v!=q[i].v) move(v, q[i].v), v=q[i].v; int anc=lca(u, v);
Xor(anc); ans[q[i].id]= now; Xor(anc);
}
}
int main(){
freopen("in","r",stdin);
n=read(); k=read(); Q=read();
for(int i=;i<=k;i++) val[i]=read();
for(int i=;i<=n;i++) w[i]=read()+w[i-];
for(int i=;i<n ;i++) ins(read(), read() );
for(int i=;i<=n;i++) a[i]=t[i]=read(); block=pow(n,(double)1.9/);
dfs(, );
while(top) pos[st[top--]]=m;
dfs(); for(int i=;i<=Q;i++){
op=read(); x=read(); y=read();
if(op) p++,q[p]=(meow){x,y,tim,p};
else tim++,cq[tim]=(cmeow){x,y,t[x]}, t[x]=y;
}
sort(q+, q++p);
modui();
for(int i=;i<=p;i++) printf("%lld\n", ans[i]);
}

【WC2013】糖果公园 [树上莫队]的更多相关文章

  1. BZOJ3052:[WC2013]糖果公园(树上莫队)

    Description Input Output Sample Input 4 3 51 9 27 6 5 12 33 13 41 2 3 21 1 21 4 20 2 11 1 21 4 2 Sam ...

  2. P4074 [WC2013]糖果公园 树上莫队带修改

    题目链接 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 nn 个游览点构 ...

  3. BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)

    题目链接 BZOJ 当然哪都能交(都比在BZOJ交好),比如UOJ #58 //67376kb 27280ms //树上莫队+带修改莫队 模板题 #include <cmath> #inc ...

  4. BZOJ 3052: [wc2013]糖果公园 | 树上莫队

    题目: UOJ也能评测 题解 请看代码 #include<cstdio> #include<algorithm> #include<cstring> #includ ...

  5. 【WC2013】 糖果公园 - 树上莫队

    问题描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩.糖果公园的结构十分奇特,它由 n 个游览点构成, ...

  6. 洛谷P4074 [WC2013]糖果公园(莫队)

    传送门 总算会树形莫队了…… 上次听说树形莫队是给树分块,实在看不懂.然后用括号序列的方法做总算能弄明白了 先说一下什么是括号序列,就是在$dfs$的时候,进入的时候记录一下,出去的时候也记录一下 拿 ...

  7. LUOGU P4074 [WC2013]糖果公园 (树上带修莫队)

    传送门 解题思路 树上带修莫队,搞了两天..终于开O2+卡常大法贴边过了...bzoj上跑了183s..其实就是把树上莫队和带修莫队结合到一起,首先求出括号序,就是进一次出一次那种的,然后如果求两个点 ...

  8. luogu4074 [WC2013]糖果公园(树上带修莫队)

    link 题目大意:给一个树,树上每个点都有一种颜色,每个颜色都有一个收益 每次修改一个点上的颜色 或询问一条链上所有颜色第i次遇到颜色j可以获得w[i]*v[j]的价值,求链上价值和 题解:树上带修 ...

  9. 【BZOJ3052】【UOJ#58】【WC2013】糖果公园(树上莫队)

    [BZOJ3052][UOJ#58][WC2013]糖果公园(树上莫队) 题面 UOJ 洛谷 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引 ...

随机推荐

  1. hdu_5104 Primes Problem()

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5104 rimes Problem Time Limit: 2000/1000 MS (Java/Oth ...

  2. [学习OpenCV攻略][016][RedHat下安装OpenCV]

    安装环境 操作系统: Red Hat Enterprise Linux Server 6.3 相关软件: ffmpeg-0.8.15.tar.bz2.cmake-3.5.1.tar.gz.OpenCV ...

  3. MapReduce 原理与 Python 实践

    MapReduce 原理与 Python 实践 1. MapReduce 原理 以下是个人在MongoDB和Redis实际应用中总结的Map-Reduce的理解 Hadoop 的 MapReduce ...

  4. 分享整理的免费API接口

    天气接口 聚合数据: http://op.juhe.cn/onebox/weather/query 用例 官方文档 来源:weather.com 百度接口: http://api.map.baidu. ...

  5. Java 中判断类和实例之间的关系

    判断类与实例的关系有以下三种方式 1.instanceof关键字,用来判断对象是否是类的实例 (对象 => 类 )   2.isAssignableFrom,用来判断类型间是否存在派生关系 (类 ...

  6. 服务器大量的fin_wait1 状态长时间存在原因分析-1

    上文描述了在出现大量fin-wait-1出现的原因,占用的内存等,这里讲一下如何处理这种情况. 首先,fin发送之后,有可能会丢弃,那么发送多少次这样的fin包呢?fin包的重传,也会采用退避方式,在 ...

  7. 寄存器(CPU原理)

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  8. 美国不同C段服务器,多ip服务器

    作为多IP服务器的拓展,多C段服务器,例如:IP分为4段,A段,B段,C段,D段.192.168.0.1/24代表着一个C段,可用IP段为192.168.0.1-255,一个C段有253个可用IP.一 ...

  9. CSS--开篇

    1,什么是CSS? 层叠样式表(Cascading Style Sheet ),定义了如何显示HTML元素,用来控制网页的样式和布局. 引入CSS后:HTML标记专门用于定义网页的内容,而使用CSS来 ...

  10. Jmeter_接口自动化基础流程概述

    这里补一篇基础的操作吧,不然总觉得没底! 1:创建一个线程组   2:添加一个cookie管理器   33333 3:设置你的信息头管理器:application/json;text/plain;ch ...