题意:

一棵树,修改一个点的颜色,询问两点路径上每种颜色的权值$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. [高并发]抢红包设计(使用redis)

    假设一个需求,在某个预告活动中准备了10w个红包,100w人在某个时间点去开抢,每人只能抢1次,如何保证性能和准确性,下面我给出我的一个设计方案,抛砖引玉 分析瓶颈 查询用户是否已参与过活动 获取一个 ...

  2. ASP.NET没有魔法——ASP.NET MVC & 分层 代码篇

    上一篇文章对如何规范使用ASP.NET进行了介绍,本章内容将根据上一篇得出的结论来修改博客应用的代码. 代码分层 综合考虑将博客应用代码分为以下几个层次: ○ 模型:代表应用程序中的数据模型,与数据库 ...

  3. 从零开始学习前端开发 — 16、CSS3圆角与阴影

    一.css3圆角: border-radius:数值+单位; 1.设置一个值:border-radius:20px; 四个方向圆角都为20px(水平半径和垂直半径相等) 2.设置两个值 border- ...

  4. 数据库 MySQL进阶之索引

    数据库的索引非常重要,基本面试数据库的问题都在索引上,所以这里小编整理出来,一方面为了自己复习,一方面也方便大家. 一,索引前传 在了解数据库索引之前,首先有必要了解一下数据库索引的数据结构基础,那么 ...

  5. UE4/Unity3D中同时捕获多高清摄像头的高效插件

    本文主要讲实现过程的一些坑. 先说下要实现的目标,主要功能在UE4/Unity中都要用,能同时捕获多个摄像头,并且捕获的图片要达到1080p25桢上,并且需要经过复杂的图片处理后丢给UE4/Unity ...

  6. 如何使用mysql命令行

    现在向大家介绍mysql命令行下,从数据库的建立到表数据的删除全过程,希望对网友有所帮助 方法/步骤 1.登陆mysql 打cmd命令终端,如果已经添加了mysql的环境变量,可以直接使用命令 mys ...

  7. maven配置文件详解

    settings.xml 本篇文章主要对maven中setting.xml配置文件进行解释 1.声明规范 <settings xmlns="http://maven.apache.or ...

  8. 关于多台机器之前session共享,sessionState mode="StateServer" 问题的困扰

    .net 多台机器共享session是很老的技术,一直很少用到session. 最近就出现了一个问题:三台前端,其中一台保存的session值死活不对,一样的环境,一样的配置文件,就是和另外两台获得的 ...

  9. javascript属性之get/set

    var o = { get x(){ return 7; }, set x(val){ console.info("不能设置x的值"); } } o.x //7 读取x值的时候,会 ...

  10. 我的Android手册

    目录解释说明 assets文件说明 app_id:机智云 app id app_secret:机智云 app secret product_key:机智云 product key wifi_type_ ...