题目


分析

考虑将树转换成序列求解,那就用欧拉序,入栈一次出栈一次正好抵消掉

注意当起点不是LCA的时候要将起点加入,剩下就是带修莫队板子题了


代码

#include <cstdio>
#include <cctype>
#include <cmath>
#include <algorithm>
#define rr register
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin)),p1==p2?EOF:*p1++)
using namespace std;
char buf[1<<21],puf[1<<21],*p1,*p2; int nowp=-1;
const int N=100011; typedef long long lll; struct rec{int x,y;}cha[N];
struct node{int y,next;}e[N<<1]; struct four{int l,r,now,rk;}q[N];
int dep[N],c[N],dfn[N],nfd[N<<1],Top[N],Q; lll w[N],now,ans[N]; bool v[N];
int siz[N],fat[N],big[N],n,Cnt[N],col[N],et=1,as[N],tot,bl,NOW,QQ,m,kuai[N<<1];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void Flush(){fwrite(puf,1,nowp+1,stdout),nowp=-1;}
inline void Putchar(char x){
if (nowp==(1<<21)) Flush();
puf[++nowp]=x;
}
inline void print(lll ans){
rr char dig[21]; rr int len=-1;
if (ans<0) Putchar('-'),ans=-ans;
do{
dig[++len]=ans%10+48,ans/=10;
}while (ans);
while (len>=0) Putchar(dig[len--]);
}
inline void dfs1(int x,int fa){
dep[x]=dep[fa]+1,fat[x]=fa,siz[x]=1;
for (rr int i=as[x],SIZ=-1;i;i=e[i].next)
if (e[i].y!=fa){
dfs1(e[i].y,x),siz[x]+=siz[e[i].y];
if (siz[e[i].y]>SIZ) big[x]=e[i].y,SIZ=siz[e[i].y];
}
}
inline void dfs2(int x,int linp){
nfd[dfn[x]=++tot]=x,Top[x]=linp;
if (big[x]) dfs2(big[x],linp);
for (rr int i=as[x];i;i=e[i].next)
if (e[i].y!=fat[x]&&e[i].y!=big[x])
dfs2(e[i].y,e[i].y);
nfd[++tot]=x;
}
inline signed Lca(int x,int y){
while (Top[x]!=Top[y]){
if (dep[Top[x]]<dep[Top[y]]) x^=y,y^=x,x^=y;
x=fat[Top[x]];
}
if (dep[x]>dep[y]) x^=y,y^=x,x^=y;
return x;
}
bool cmp(four a,four b){
if (kuai[a.l]^kuai[b.l]) return a.l<b.l;
if (kuai[a.r]^kuai[b.r]) return kuai[a.l]&1?a.r<b.r:a.r>b.r;
return (kuai[a.l]^kuai[a.r])&1?a.now<b.now:a.now>b.now;
}
inline void doit(int x){
v[x]^=1;
if (v[x]) now+=w[++Cnt[col[x]]]*c[col[x]];
else now-=w[Cnt[col[x]]--]*c[col[x]];
}
inline void update(int Now){
rr int x=cha[Now].x,Y=cha[Now].y,X=col[x];
if (v[x]) now+=w[++Cnt[Y]]*c[Y]-w[Cnt[X]--]*c[X];
col[x]=Y,cha[Now].y=X;
}
signed main(){
n=iut(),m=iut(),QQ=iut();
for (rr int i=1;i<=m;++i) c[i]=iut();
for (rr int i=1;i<=n;++i) w[i]=iut();
for (rr int i=1;i<n;++i){
rr int x=iut(),y=iut();
e[++et]=(node){y,as[x]},as[x]=et;
e[++et]=(node){x,as[y]},as[y]=et;
}
for (rr int i=1;i<=n;++i) col[i]=iut();
dfs1(1,0),dfs2(1,1);
for (;QQ;--QQ){
rr int typ=iut(),x=iut(),y=iut();
if (typ){
if (dfn[x]>dfn[y]) x^=y,y^=x,x^=y;
q[++Q]=(four){dfn[x],dfn[y],NOW,Q};
}else cha[++NOW]=(rec){x,y};
}
bl=pow(n,NOW?2.0/3:1.0/2);
for (rr int i=1;i<=n*2;++i) kuai[i]=i/bl;
rr int x,y,l,r,Z=0,z; sort(q+1,q+1+Q,cmp);
for (rr int i=1,L=q[1].l,R=L-1;i<=Q;++i){
x=nfd[l=q[i].l],y=nfd[r=q[i].r],z=q[i].now;
while (L>l) doit(nfd[--L]);
while (L<l) doit(nfd[L++]);
while (R>r) doit(nfd[R--]);
while (R<r) doit(nfd[++R]);
while (Z>z) update(Z--);
while (Z<z) update(++Z);
rr int lca=Lca(x,y);
if (x^lca) doit(x),doit(lca);
ans[q[i].rk]=now;
if (x^lca) doit(x),doit(lca);
}
for (rr int i=1;i<=Q;++i) print(ans[i]),Putchar(10);
Flush();
return 0;
}

#树上带修莫队,树链剖分#洛谷 4074 [WC2013]糖果公园的更多相关文章

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

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

  2. 【BZOJ-3052】糖果公园 树上带修莫队算法

    3052: [wc2013]糖果公园 Time Limit: 200 Sec  Memory Limit: 512 MBSubmit: 883  Solved: 419[Submit][Status] ...

  3. bzoj4129 Haruna’s Breakfast 树上带修莫队+分块

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4129 题解 考虑没有修改的序列上的版本应该怎么做: 弱化的题目应该是这样的: 给定一个序列,每 ...

  4. BZOJ3052: [wc2013]糖果公园【树上带修莫队】

    Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 HINT 思路 非常模板的树上带修莫队 真的 ...

  5. BZOJ 4129 Haruna’s Breakfast ( 树上带修莫队 )

    题面 求树上某路径上最小的没出现过的权值,有单点修改 添加链接描述 分析 树上带修莫队板题,问题是怎么求最小的没出现过的权值. 因为只有nnn个点,所以没出现过的最小值一定在[0,n][0,n][0, ...

  6. BZOJ 3052/Luogu P4074 [wc2013]糖果公园 (树上带修莫队)

    题面 中文题面,难得解释了 BZOJ传送门 Luogu传送门 分析 树上带修莫队板子题... 开始没给分块大小赋初值T了好一会... CODE #include <bits/stdc++.h&g ...

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

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

  8. BZOJ 3052 树上带修莫队

    思路: 就是把带修莫队移到了树上 块的大小开到(n^2/3)/2 比较好- 这是一个卡OJ好题 //By SiriusRen #include <cmath> #include <c ...

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

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

  10. NOI模拟 颜色 - 带修莫队/树套树

    题意: 一个颜色序列,\(a_1, a_2, ...a_i\)表示第i个的颜色,给出每种颜色的美丽度\(w_i\),定义一段颜色的美丽值为该段颜色的美丽值之和(重复的只计算一次),每次都会修改某个位置 ...

随机推荐

  1. Mybatis模糊查询无法确定参数$1的数据类型: ERROR: could not determine data type of parameter $1

    Mybatis模糊查询无法确定参数$1的数据类型: 报错ERROR: could not determine data type of parameter $1 修改前: SELECT count(0 ...

  2. python字典操作的大O效率

  3. 内建函数iter(),第三个参数哨兵用法

    循环读取文件常见写法 CHUNKSIZE=8192 def reader(s): while True: data = s.recv(CHUNKSIZE) if data == b'': break ...

  4. Jenkins配置SpringBoot项目启动脚本

    目录 背景 脚本编写 变量说明 使用说明 Q&A jenkins部署时错误 背景 上一篇Jenkins配置介绍了Jenkins远程部署的相关配置和步骤,但是最后的部署脚本只适用于部署原始tom ...

  5. C++ STL 容器-Vector类型

    C++ STL 容器-Vector类型 std::vector是C++标准库中的一个动态数组容器,它提供了随机访问迭代器,因此你可以像使用普通数组一样使用vector. vector容器可以动态地增长 ...

  6. centos解决 pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.

    一.下载 openssl 编译安装 openssl 官方下载地址:https://www.openssl.org/source/ wget https://github.com/openssl/ope ...

  7. Zabbix与乐维监控对比分析(四)——告警管理篇

    在前面发布的Zabbix与乐维监控对比分析文章中,我们评析了二者在架构与性能.Agent管理.自动发现.权限管理.对象管理等方面的差异.接下来让我们一起看看二者在告警管理方面的差异. 告警管理是所有I ...

  8. 选择单词后 按 ctrl + space 单词发音

    需求: 在ide或其他地方,经常有单词发音不是很确定,但并不要很详细 就听个单词发音. 确定快捷键: 左手单手操作,我键盘上貌似就 左边的ctrl和空格键 还没有设定 翻译软件: 使用 pc端的 欧路 ...

  9. Git: Host key verification failed(主机密钥验证失败)

    换了新电脑Y7000 10750H,之前的项目提示这个,本以为删个什么文件,搜了一阵,没找到答案. 简单粗暴的方法就是再git clone一下,就ok了,这点很不爽.暂时先这么解决了.

  10. SQL注入详细讲解概括—盲注

    SQL注入详细讲解概括-盲注 1.盲注简单理解 2.盲注必学函数 3.布尔盲注 4.时间盲注 一.盲注简单理解 What is 盲注? It is 在服务器没有错误回显的时候完成的注入攻击 数据库把报 ...