[WC2013]糖果公园
Description
给你一棵 $n$ 个节点,有 $m$种颜色的树。每个节点上有一个颜色。定义一条树上路径的价值为
$sum_c V_c(\sum_{i=1}^{tim_c}W_i)$
其中 $V,W$已经给出, $tim_c$ 表示路径上 $c$ 颜色的节点数。
现在给出 $q$ 个操作,让你实现:
- 修改节点颜色;
- 询问树上路径的价值。
$1\leq n,m,q\leq 100000$
转载自Navi_Awson
如果这题出在序列上而不是在树上,很容易用莫队求解。
考虑用类似的方法,我们将树分块,采用[SCOI 2005]王室联邦的方法。
对于树上分块的复杂度和块的大小的选取可以参见ljh的博客,这里摘出了一些:
设 $block_{num}$ 为块数, $block_{size}$ 为块的大小,则有 $block_{num}\times block_{size}=n$ ,在证明中我们假设 $n,q$ 同阶。
设块对 $(block_i,block_j)$ ,易知这样的块对不会超过 $block_{size}^2$ 个。
对于块对内的操作:我们考虑总复杂度,左端点共移动至多 $O(q\times block_{size})$ ,右端点亦是。时间共移动至多 $O(block_{num}^2\times q)$ 。故这一部分的复杂度为 $O(n\times(block_{size}+block_{num}^2))$ 。
对于块与块之间的操作,不超过 $block_{num}^2$ 次:左端第移动一次,最多 $O(n)$ ,右端点亦是如此。时间最多移动 $O(q)=O(n)$ 。故这一部分复杂度为 $O(block_{num}^2\times n)$。
故总复杂度为 $O(n\times(block_{size}+block_{num}^2))$。
可以证明当 $block_{size}=n^{\frac{2}{3}}$ 时, $block_{num}=n^{\frac{1}{3}}$ ,复杂度最优,为 $O(n^{\frac{5}{3}})$ 。
至于莫队的操作,就是将序列中移动左右端点变成在树上移动路径的两个端点。对于修改,我们同样是模拟时间倒流和消逝。
那么怎么去移动结点来保证提取出路径?
考虑我们树上的所有结点,实际上可以认为是 $0/1$ 状态——计入答案或者未计入答案。
考虑用类似于异或的思想来执行操作,比如:计入答案再从答案中去掉,等于异或了两次 $1$ ,就等于原来的数。假设这次的起点、终点为 $u,v$ ,上次为 $x,y$ ,那么可以对 $x$ 到 $u$ 的路径、 $v$ 到 $y$ 的路径进行一次取 $xor$ 操作。注意的是对 $lca$ 不做处理,这样就能保证每次操作之后图上打上标记的点只在 $(u,lca)$和 $(v,lca)$ 的路径上(不包括 $lca$ )。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long lol;
struct ZYYS
{
int x,y,p,id;
}p[],q[];
struct Node
{
int next,to;
}edge[];
int num,head[],block[],tot,size[],son[],block_size,block_num,cnt,s[];
int top[],dfn[],dep[],fa[],rev[],c[],n,m,Q,pre[],cntp,cntq;
int curl,curr,curp;
lol sum,v[],w[],ans[];
bool cmp(ZYYS a,ZYYS b)
{
if (block[a.x]==block[b.x])
{
if (block[a.y]==block[b.y]) return a.id<b.id;
else return block[a.y]<block[b.y];
}
else return block[a.x]<block[b.x];
}
void add(int u,int v)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
}
void dfs1(int x,int pa)
{int i;
int bot=tot;
fa[x]=pa;
size[x]=;
dep[x]=dep[pa]+;
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v==pa) continue;
dfs1(v,x);
if (size[son[x]]<size[v]) son[x]=v;
size[x]+=size[v];
if (tot-bot>=block_size)
{
++cnt;
while (tot>bot)
{
block[s[tot--]]=cnt;
}
}
}
s[++tot]=x;
}
void dfs2(int x,int pa,int tp)
{int i;
top[x]=tp;
dfn[x]=++tot;
if (son[x]) dfs2(son[x],x,tp);
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v==pa||v==son[x]) continue;
dfs2(v,x,v);
}
}
int get_lca(int x,int y)
{
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
if (dep[x]<dep[y]) return x;
return y;
}
void reverse(int x)
{
if (rev[x]) sum-=v[c[x]]*w[s[c[x]]],s[c[x]]--;
else s[c[x]]++,sum+=v[c[x]]*w[s[c[x]]];
rev[x]^=;
}
void update(int x,int y)
{
if (rev[x]) reverse(x),c[x]=y,reverse(x);
else c[x]=y;
}
void move(int x,int y)
{
while (x!=y)
{
if (dep[x]<dep[y]) swap(x,y);
reverse(x);
x=fa[x];
}
}
int main()
{int i,uu,vv,opt,x,y;
cin>>n>>m>>Q;
for (i=;i<=m;i++)
scanf("%lld",&v[i]);
for (i=;i<=n;i++)
scanf("%lld",&w[i]);
block_size=pow(n,0.666667);
block_num=n/block_size;
for (i=;i<n;i++)
{
scanf("%d%d",&uu,&vv);
add(uu,vv);add(vv,uu);
}
for (i=;i<=n;i++)
{
scanf("%d",&c[i]);
pre[i]=c[i];
}
dfs1(,);
++cnt;
while (tot)
{
block[s[tot--]]=cnt;
}
tot=;
memset(s,,sizeof(s));
dfs2(,,);
for (i=;i<=Q;i++)
{
scanf("%d",&opt);
if (opt==)
{
scanf("%d%d",&x,&y);
p[++cntp]=(ZYYS){x,y,pre[x],};
pre[x]=y;
}
else
{
scanf("%d%d",&x,&y);
q[++cntq]=(ZYYS){x,y,cntp,cntq};
}
}
sort(q+,q+cntq+,cmp);
curl=;curr=;curp=;
for (i=;i<=cntq;i++)
{
while (curp<q[i].p) {curp++;update(p[curp].x,p[curp].y);}
while (curp>q[i].p) {update(p[curp].x,p[curp].p);curp--;}
move(curl,q[i].x);curl=q[i].x;
move(curr,q[i].y);curr=q[i].y;
int lca=get_lca(curl,curr);
reverse(lca);
ans[q[i].id]=sum;
reverse(lca);
}
for (i=;i<=cntq;i++)
{
printf("%lld\n",ans[i]);
}
}
[WC2013]糖果公园的更多相关文章
- bzoj 3052: [wc2013]糖果公园 带修改莫队
3052: [wc2013]糖果公园 Time Limit: 250 Sec Memory Limit: 512 MBSubmit: 506 Solved: 189[Submit][Status] ...
- 洛谷 P4074 [WC2013]糖果公园 解题报告
P4074 [WC2013]糖果公园 糖果公园 树上待修莫队 注意一个思想,dfn序处理链的方法,必须可以根据类似异或的东西,然后根据lca分两种情况讨论 注意细节 Code: #include &l ...
- AC日记——[WC2013]糖果公园 cogs 1817
[WC2013]糖果公园 思路: 带修改树上莫队(模板): 来,上代码: #include <cmath> #include <cstdio> #include <cst ...
- COGS1817. [WC2013]糖果公园
1817. [WC2013]糖果公园 ★★★☆ 输入文件:park.in 输出文件:park.out 简单对比时间限制:8 s 内存限制:512 MB [题目描述] Candyland ...
- 【BZOJ3052】[wc2013]糖果公园 带修改的树上莫队
[BZOJ3052][wc2013]糖果公园 Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 ...
- [BZOJ3052][UOJ#58][WC2013]糖果公园
[BZOJ3052][UOJ#58][WC2013]糖果公园 试题描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来 ...
- 【BZOJ】3052: [wc2013]糖果公园 树分块+带修改莫队算法
[题目]#58. [WC2013]糖果公园 [题意]给定n个点的树,m种糖果,每个点有糖果ci.给定n个数wi和m个数vi,第i颗糖果第j次品尝的价值是v(i)*w(j).q次询问一条链上每个点价值的 ...
- 【Luogu P4074】[WC2013]糖果公园(树上带修改莫队)
题目描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 \(n\) 个游 ...
- 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 个游览点构 ...
随机推荐
- 2017-2018-1 1623 bug终结者 冲刺006
bug终结者 冲刺006 by 20162328 蔡文琛 今日任务:音频素材添加 又是新的一天,小组项目有了很大的起色,已经可以在手机上试玩了. 添加背景音乐能使我们的游戏锦上添花. 音频资源需求 需 ...
- C++类型萃取
stl中的迭代器和C++中的类型萃取: http://www.itnose.net/detail/6487058.html 赐教!
- 2017北京国庆刷题Day1 afternoon
期望得分:100+100+100=300 实际得分:100+100+100=300 T1 一道图论好题(graph) Time Limit:1000ms Memory Limit:128MB 题目 ...
- java语法基础(总结)
1,关键字:其实就是某种语言赋予了特殊含义的单词. 保留字:其实就是还没有赋予特殊含义,但是准备日后要使用过的单词. 2,标示符:其实就是在程序中自定义的名词.比如类名,变量名,函数名.包含 0-9. ...
- selenium多个标签页的切换(弹出新页面的切换)
1_windows = driver.current_window_handle #定位当前页面句柄 all_handles = driver.window_handles #获取全部页面句柄 for ...
- SpringCloud的Archaius - 动态管理属性配置
参考链接:http://www.th7.cn/Program/java/201608/919853.shtml 一.Archaius是什么? Archaius用于动态管理属性配置文件. 参考自Gett ...
- python常用运算符
1. / 浮点除法,就算分子分母都是int类型,也返回float类型,比如我们用4/2,返回2.0 2. // 整数除法,根据分子分母的不同组合,返回的值有差异. 正数//正数,取整,比如5//3,返 ...
- linux搭建django项目基本步骤
一 linux下django基本项目搭建流程:M model 用于与数据库交互V view 接受前台请求 调用model获取结果,调用T获取页面,返回给前台T template 接受view的要求 生 ...
- 未能加载文件或程序集“ RevitAPIUI.dll”
revit二次开发中遇到的问题 RevitAPIUI.dll 只能 Native Library 中执行: 脱离了Native Library,API是跑不起来的 . 检查程序流程:登录,配置,启动r ...
- Mysql启动时提示:Another MySQL daemon already running with the same unix socket.
场景:vmvare虚拟机.centos7.mysql5.7 解决: mv /var/lib/mysql/mysql.sock /var/lib/mysql/mysql.sock.bak 参考: htt ...