BZOJ3052 [wc2013] 糖果公园 【树上莫队】
树上莫队和普通的序列莫队很像,我们把树进行dfs,然后存一个长度为2n的括号序列,就是一个点进去当作左括号,出来当作右括号,然后如果访问从u到v路径,我们可以转化成括号序列的区间,记录x进去的时候编号为f[x],出来时为g[x],然后分类讨论一下(f[u]<f[v]),如果u和v的lca不是u,那么就是从g[u]到f[v],否则就是lca的f到另一个点的f,(可以自己试一下,中间过程没有用的点正好就抵消掉了)这里要注意一下,从g[u]到f[v]的时候我们会少掉lca这个点,特殊处理一下即可,然后按照普通莫队排一下序,暴力就行了。 —— by VANE
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=;
int n,m,cnt1,cnt2,tot,clk,f[N],g[N];
vector<int> M[N];
int id[N<<],blg[N<<];
int bin[],pos[N],fa[N][],c[N],d[N];
int v[N],w[N],last[N],u[N];
bool vis[N];
struct node
{
int l,r,t,id;
}a[N],b[N];
ll ans[N],sum;
void dfs(int x)
{
f[x]=++clk;id[clk]=x;
for(int i=;bin[i]<=d[x];++i)
fa[x][i]=fa[fa[x][i-]][i-];
for(int i=;i<M[x].size();++i)
{
int y=M[x][i];
if(y!=fa[x][])
{
fa[y][]=x;
d[y]=d[x]+;
dfs(y);
}
}
g[x]=++clk;
id[clk]=x;
}
int lca(int x,int y)
{
if(d[x]<d[y]) swap(x,y);
int tmp=d[x]-d[y];
for(int i=;bin[i]<=tmp;++i)
if(tmp&bin[i]) x=fa[x][i];
if(x==y) return x;
for(int i=;i>=;--i)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][];
}
bool cmp(node x,node y)
{
if(blg[x.l]<blg[y.l]) return ;
if(blg[x.l]==blg[y.l]&&blg[x.r]<blg[y.r]) return ;
if(blg[x.l]==blg[y.l]&&blg[x.r]==blg[y.r]) return x.t<y.t;
return ;
}
void modify(int x)
{
if(vis[x]) sum-=1ll*v[c[x]]*w[u[c[x]]--];
else sum+=1ll*v[c[x]]*w[++u[c[x]]];
vis[x]^=;
}
void change(int x,int y)
{
if(vis[x]) {modify(x);c[x]=y;modify(x);}
else c[x]=y;
}
int main()
{
int cas;
scanf("%d%d%d",&n,&m,&cas);
bin[]=;for(int i=;i<=;++i) bin[i]=bin[i-]<<;
for(int i=;i<=m;++i) scanf("%d",v+i);
for(int i=;i<=n;++i) scanf("%d",w+i);
for(int i=;i<n;++i)
{
int l,r;scanf("%d%d",&l,&r);
M[l].push_back(r);
M[r].push_back(l);
}
for(int i=;i<=n;++i)
scanf("%d",c+i),last[i]=c[i];
int sz=pow(n,2.0/);
dfs();
for(int i=;i<=clk;++i) blg[i]=(i-)/sz;
while(cas--)
{
int l,r,t;
scanf("%d%d%d",&t,&l,&r);
if(t)
{
if(f[l]>f[r]) swap(l,r);
a[++cnt1].r=f[r];a[cnt1].t=cnt2;
a[cnt1].id=cnt1;
a[cnt1].l=(lca(l,r)==l)?f[l]:g[l];
}
else
{
b[++cnt2].l=l;b[cnt2].t=last[l];
last[l]=b[cnt2].r=r;
}
}
sort(a+,a++cnt1,cmp);
int l=,r=,t=;
for(int i=;i<=cnt1;++i)
{
for(;t<=a[i].t;++t) change(b[t].l,b[t].r);
for(;t>a[i].t;--t) change(b[t].l,b[t].t);
while(l>a[i].l) modify(id[--l]);
while(l<a[i].l) modify(id[l++]);
while(r>a[i].r) modify(id[r--]);
while(r<a[i].r) modify(id[++r]);
int x=id[l],y=id[r],tmp=lca(x,y);
if(x!=tmp&&y!=tmp) {modify(tmp);ans[a[i].id]=sum;modify(tmp);}
else ans[a[i].id]=sum;
}
for(int i=;i<=cnt1;++i)
printf("%lld\n",ans[i]);
}
BZOJ3052 [wc2013] 糖果公园 【树上莫队】的更多相关文章
- 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 ...
- P4074 [WC2013]糖果公园 树上莫队带修改
题目链接 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 nn 个游览点构 ...
- BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)
题目链接 BZOJ 当然哪都能交(都比在BZOJ交好),比如UOJ #58 //67376kb 27280ms //树上莫队+带修改莫队 模板题 #include <cmath> #inc ...
- BZOJ 3052: [wc2013]糖果公园 | 树上莫队
题目: UOJ也能评测 题解 请看代码 #include<cstdio> #include<algorithm> #include<cstring> #includ ...
- 【WC2013】 糖果公园 - 树上莫队
问题描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩.糖果公园的结构十分奇特,它由 n 个游览点构成, ...
- 【WC2013】糖果公园 [树上莫队]
题意: 一棵树,修改一个点的颜色,询问两点路径上每种颜色的权值$val[c]$*出现次数的权值$cou[w[c]]$的和 sro VFK 树上莫队 按照王室联邦的方法分块,块的大小直径个数有保证,并不 ...
- 洛谷P4074 [WC2013]糖果公园(莫队)
传送门 总算会树形莫队了…… 上次听说树形莫队是给树分块,实在看不懂.然后用括号序列的方法做总算能弄明白了 先说一下什么是括号序列,就是在$dfs$的时候,进入的时候记录一下,出去的时候也记录一下 拿 ...
- 【BZOJ-3052】糖果公园 树上带修莫队算法
3052: [wc2013]糖果公园 Time Limit: 200 Sec Memory Limit: 512 MBSubmit: 883 Solved: 419[Submit][Status] ...
- LUOGU P4074 [WC2013]糖果公园 (树上带修莫队)
传送门 解题思路 树上带修莫队,搞了两天..终于开O2+卡常大法贴边过了...bzoj上跑了183s..其实就是把树上莫队和带修莫队结合到一起,首先求出括号序,就是进一次出一次那种的,然后如果求两个点 ...
随机推荐
- 【BZOJ】4293: [PA2015]Siano 线段树上二分
[题意]给定n棵高度初始为0的草,每天每棵草会长高a[i],m次收割,每次在d[i]天将所有>b[i]的草收割到b[i],求每次收割量.n<=500000. [算法]线段树上二分 [题解] ...
- js常见易错点
原文:http://www.jianshu.com/p/1c77853d4f01 前言 本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函 ...
- Vue SPA 首屏加载优化实践
写在前面 本文记录笔者在Vue SPA项目首屏加载优化过程中遇到的一些坑及优化方案! 我们以 vue-cli 工具为例,使用 vue-router 搭建SPA应用,UI框架选用 element-ui ...
- Spring Boot学习——单元测试
本随笔记录使用Spring Boot进行单元测试,主要是Service和API(Controller)进行单元测试. 一.Service单元测试 选择要测试的service类的方法,使用idea自动创 ...
- Python编程规范精简版
用四个空格缩进,不要用tab键:四个空格是在较小缩进(可以允许更大的嵌套深度)和较大缩进(可读性更好)之间的一个很好的折中.制表符会带来混乱,最好不要使用: 包装行保证每行不超过79个字符:这对那些使 ...
- C语言地址对齐(转)--网络编程之结构体大小的计算
什么是地址对齐? 现代计算机中内存空间都是按照字节(byte)划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数 ...
- SSD回归类物体检测
本宝宝最近心情不会,反正这篇也是搬用别人博客的了:(SSD就是YOLO+anchor(不同feature map 作为input)) 引言 这篇文章是在YOLO[1]之后的一篇文章,这篇文章目前是一篇 ...
- 修改TortoiseSVN客户端登陆用户
TortoiseSVN是一款常用且非常不错的SVN工具,俗称小乌龟.开发的时候,经常用的当然是TortoiseSVN客户端了. 一般情况下,TortoiseSVN服务器提供的IP地址和用户都不会变,而 ...
- Linux 基础——文件搜索命令find
一.find命令的好处 有时会经常在目录下找文件或目录的具体存放在哪,但是该目录下的文件又很多不好找出.这时并不需要手动查看所有的文件,用find命令来帮助查找就行了.所以文件或目录一定归好类,存放有 ...
- 秀尔算法:破解RSA加密的“不灭神话” --zz
http://netsecurity.51cto.com/art/201508/488766.htm RSA加密曾被视为最可靠的加密算法,直到秀尔算法出现,打破了RSA的不灭神话. RSA加密 VS ...