#树上带修莫队,树链剖分#洛谷 4074 [WC2013]糖果公园
分析
考虑将树转换成序列求解,那就用欧拉序,入栈一次出栈一次正好抵消掉
注意当起点不是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]糖果公园的更多相关文章
- luogu4074 [WC2013]糖果公园(树上带修莫队)
link 题目大意:给一个树,树上每个点都有一种颜色,每个颜色都有一个收益 每次修改一个点上的颜色 或询问一条链上所有颜色第i次遇到颜色j可以获得w[i]*v[j]的价值,求链上价值和 题解:树上带修 ...
- 【BZOJ-3052】糖果公园 树上带修莫队算法
3052: [wc2013]糖果公园 Time Limit: 200 Sec Memory Limit: 512 MBSubmit: 883 Solved: 419[Submit][Status] ...
- bzoj4129 Haruna’s Breakfast 树上带修莫队+分块
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4129 题解 考虑没有修改的序列上的版本应该怎么做: 弱化的题目应该是这样的: 给定一个序列,每 ...
- BZOJ3052: [wc2013]糖果公园【树上带修莫队】
Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 HINT 思路 非常模板的树上带修莫队 真的 ...
- BZOJ 4129 Haruna’s Breakfast ( 树上带修莫队 )
题面 求树上某路径上最小的没出现过的权值,有单点修改 添加链接描述 分析 树上带修莫队板题,问题是怎么求最小的没出现过的权值. 因为只有nnn个点,所以没出现过的最小值一定在[0,n][0,n][0, ...
- BZOJ 3052/Luogu P4074 [wc2013]糖果公园 (树上带修莫队)
题面 中文题面,难得解释了 BZOJ传送门 Luogu传送门 分析 树上带修莫队板子题... 开始没给分块大小赋初值T了好一会... CODE #include <bits/stdc++.h&g ...
- LUOGU P4074 [WC2013]糖果公园 (树上带修莫队)
传送门 解题思路 树上带修莫队,搞了两天..终于开O2+卡常大法贴边过了...bzoj上跑了183s..其实就是把树上莫队和带修莫队结合到一起,首先求出括号序,就是进一次出一次那种的,然后如果求两个点 ...
- BZOJ 3052 树上带修莫队
思路: 就是把带修莫队移到了树上 块的大小开到(n^2/3)/2 比较好- 这是一个卡OJ好题 //By SiriusRen #include <cmath> #include <c ...
- 洛谷P4074 [WC2013]糖果公园(莫队)
传送门 总算会树形莫队了…… 上次听说树形莫队是给树分块,实在看不懂.然后用括号序列的方法做总算能弄明白了 先说一下什么是括号序列,就是在$dfs$的时候,进入的时候记录一下,出去的时候也记录一下 拿 ...
- NOI模拟 颜色 - 带修莫队/树套树
题意: 一个颜色序列,\(a_1, a_2, ...a_i\)表示第i个的颜色,给出每种颜色的美丽度\(w_i\),定义一段颜色的美丽值为该段颜色的美丽值之和(重复的只计算一次),每次都会修改某个位置 ...
随机推荐
- 硬件开发笔记(十一):Altium Designer软件介绍、安装过程和打开pcb工程测试
前言 前面做高速电路,选择是阿li狗,外围电路由于读者熟悉AD,使用使用ad比较顺手,非高速电路就使用AD了,其实AD也可以做高速电路,由于笔者从13年开始做硬是从AD9开始的,所以开始切入AD做 ...
- Linux驱动开发笔记(二):ubuntu系统从源码编译安装gcc7.3.0编译器
前言 编译ubuntu驱动之前,发现使用的gcc是7.3.0,而使用apt管理和下载的都无法直接或间接安装gcc7.3.0,于是只能从源码安装gcc7.3.0编译器. GCC 概述 GCC ...
- Singularity容器
"""参考文档 https://apptainer.org/user-docs/master/build_a_container.html ""&qu ...
- 数据分析day02
案例 需求:双均线策略制定 1.使用tushare包获取某股票的历史行情数据 2.计算该股票历史数据的5日均线和30日均线 - 什么是均线? - 对于每一个交易日,都可以计算出前N天的移动平均值,然后 ...
- Redis缓存应用场景
记录一下自己的听课笔记,看的网课. 参考资料:https://zhuanlan.zhihu.com/p/157717158 常见应用场景 1 数据缓存 缓存一些常用的.经常访问的.不经常变化的数据,也 ...
- 【Azure 应用服务】收集App Service 关于Availability Zone, Health check 以及 Traffic Manager的文档,并了解高可用(HA)和灾备(DR)
问题描述 收集App Service 关于Availability Zone, Health check 以及 Traffic Manager的文档,并了解高可用(HA)和灾备(DR)的具体办法 问题 ...
- Dockerfile编写(备份)
1-使用#注释 2-Dockerfile 主体内容分为四部分:基础镜像信息. 维护者信息. 镜像操作指令和容器启动时执行指令 简单示例: FROM xxx:latest #基于xxx:late ...
- 「实操」适配 NebulaGraph 新版本与压测实践
本文来自邦盛科技-知识图谱团队-繁凡,本文以 NebulaGraph v3.1.0 为例. 前言 NebulaGraph v3.1 版本已经发布有一段时间了,但是我们的项目之前是基于 v2.6.1 版 ...
- 【项目实战】SpringBoot+vue+iview打造一个极简个人博客系统
基于SpringBoot+vue+iview个人极简博客 项目介绍 个人极简博客 [个人极简博客]是一个适用于初学者学习的博客系统,其中包含文章分类.写文章.标签管理.用户管理等基础功能,代码简洁注释 ...
- 我的Java面试资料推荐
看法 每年去大厂试试水,借此来评估自己的能力.价值和不足,或许还能拿到一个好offer,是个合格程序员的职业表现 大厂面试,基本都是:先过算法,检验面试人的智商和逻辑能力:之后才考察语言.设计.中间件 ...