问题描述

Candyland 有一座糖果公园,公园里不仅有美丽的风景、好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩。
糖果公园的结构十分奇特,它由 n 个游览点构成,每个游览点都有一个糖果发放处,我们可以依次将游览点编号为 1 至 n。有 n – 1 条 双向道路 连接着这些游览点,并且整个糖果公园都是 连通的 ,即从任何一个游览点出发都可以通过这些道路到达公园里的所有其它游览点。
糖果公园所发放的糖果种类非常丰富,总共有 m 种,它们的编号依次为 1至 m。每一个糖果发放处都只发放某种特定的糖果,我们用 C i 来表示 i 号游览点的糖果。
来到公园里游玩的游客都 不喜欢走回头路 ,他们总是从某个特定的游览点出发前往另一个特定的游览点,并游览途中的景点,这条路线一定是唯一的。他们经过每个游览点,都可以品尝到一颗对应种类的糖果。
大家对不同类型糖果的喜爱程度都不尽相同。根据游客们的反馈打分,我们得到了糖果的美味指数,第 i 种糖果的美味指数为 V i 。另外,如果一位游客反复地品尝同一种类的糖果,他肯定会觉得有一些腻。根据量化统计,我们得到了游客第 i 次品尝某类糖果的新奇指数 W i 。如果一位游客第 i 次品尝第 j 种糖果,那么他的愉悦指数 H 将会增加对应的美味指数与新奇指数的乘积,即 V j W i 。这位游客游览公园的愉悦指数最终将是这些乘积的和。
当然,公园中每个糖果发放点所发放的糖果种类不一定是一成不变的。有时,一些糖果点所发放的糖果种类可能会更改(也只会是 m 种中的一种),这样的目的是能够让游客们总是感受到惊喜。
糖果公园的工作人员小 A 接到了一个任务,那就是 根据公园最近的数据统计出每位游客游玩公园的愉悦指数 。但数学不好的小 A 一看到密密麻麻的数字就觉得头晕,作为小 A 最好的朋友,你决定帮他一把。

思路

树上莫队板子 qwq

#include <bits/stdc++.h>
#define ri register
using namespace std;
typedef long long ll;
const int maxn = 100000 + 10;
int n,m,Q,cntq,cntc,Time,block,mark[maxn],dep[maxn],cnt[maxn],father[maxn][20],dfn[maxn],v[maxn],w[maxn],x[maxn],edgecnt,first[maxn];
ll tot,ans[maxn];
struct edge {
int to,next;
}eg[maxn];
inline void addedge(ri int u,ri int v){
eg[++edgecnt] = (edge){v,first[u]}; first[u] = edgecnt;
eg[++edgecnt] = (edge){u,first[v]}; first[v] = edgecnt;
}
inline int read() {
char ch = getchar();
ri int x = 0, f = 1;
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while ('0' <= ch && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
void write(ll x) {
ri ll y = 10,len = 1;
while (y <= x) { y *= 10; len++; }
while (len--) { y /= 10; putchar(x/y+48); x %= y; }
}
struct Query {
int l,r,num,c;
inline bool operator < (Query cmp) const {
if (dfn[l]/block != dfn[cmp.l]/block) return dfn[l]/block < dfn[cmp.l]/block;
if (dfn[r]/block != dfn[cmp.r]/block) return dfn[r]/block < dfn[cmp.r]/block;
return c < cmp.c;
}
}q[maxn];
struct Change {
int pos,to;
}c[maxn];
inline void dfs(ri int now,ri int fa) {
father[now][0] = fa;
dfn[now] = ++Time;
dep[now] = dep[fa]+1;
ri size_t i;
for (i = first[now];~i;i = eg[i].next)
if (eg[i].to != fa) dfs(eg[i].to,now);
}
inline void init() {
ri int i,j;
for (j = 1;(1<<j) <= n;j++)
for (i = 1;i <= n;i++)
father[i][j] = father[father[i][j-1]][j-1];
}
inline int lca(ri int a,ri int b) {
if (dep[a] < dep[b]) swap(a,b);
ri int i,j; for (i = 0;(1<<i) <= dep[a];i++); i--;
for (j = i;j >= 0;j--)
if (dep[a]-(1<<j) >= dep[b]) a = father[a][j];
if (a == b) return a;
for (j = i;j >= 0;j--)
if (father[a][j] != father[b][j]) a = father[a][j],b = father[b][j];
return father[a][0];
}
inline void reverse(ri int i) {
if (mark[i]) { mark[i] ^= 1; tot -= (long long)w[cnt[x[i]]--]*(long long)v[x[i]]; }
else { mark[i] ^= 1; tot += (long long)w[++cnt[x[i]]]*(long long)v[x[i]]; }
}
inline void change(ri int i) {
if (!mark[c[i].pos]) swap(c[i].to,x[c[i].pos]);
else {
reverse(c[i].pos);
swap(c[i].to,x[c[i].pos]);
reverse(c[i].pos);
}
}
int main() {
memset(first,-1,sizeof(first));
n = read(),m = read(),Q = read();
block = pow(n,2.0/3)*0.5;
ri int i,t,X,y;
for (i = 1;i <= m;i++) v[i] = read();
for (i = 1;i <= n;i++) w[i] = read();
for (i = 1;i < n;i++) X = read(),y = read(),addedge(X,y);
for (i = 1;i <= n;i++) x[i] = read();
dfs(1,0);
init();
for (i = 1;i <= Q;i++) {
t = read(),X = read(),y = read();
if (!t) c[++cntc].pos = X,c[cntc].to = y;
else q[++cntq].l = X,q[cntq].r = y,q[cntq].num = cntq,q[cntq].c = cntc;
}
sort(q+1,q+cntq+1);
if (dfn[q[1].l] > dfn[q[1].r]) swap(q[1].l,q[1].r);
ri ll LCA = lca(q[1].l,q[1].r),curl = q[1].l,curr = q[1].r,curc = 0,l = curl,r = curr;
while (l != LCA) reverse(l),l = father[l][0];
while (r != LCA) reverse(r),r = father[r][0];
while (curc < q[1].c) change(++curc);
reverse(LCA); ans[q[1].num] = tot; reverse(LCA);
for (i = 2;i <= cntq;i++) {
if (dfn[q[i].l] > dfn[q[i].r]) swap(q[i].l,q[i].r);
LCA = lca(q[i].r,curr),l = curr,r = q[i].r;
while (l != LCA) reverse(l),l = father[l][0];
while (r != LCA) reverse(r),r = father[r][0];
LCA = lca(q[i].l,curl),l = curl,r = q[i].l;
while (l != LCA) reverse(l),l = father[l][0];
while (r != LCA) reverse(r),r = father[r][0];
while (curc < q[i].c) change(++curc);
while (curc > q[i].c) change(curc--);
LCA = lca(q[i].l,q[i].r);
reverse(LCA); ans[q[i].num] = tot; reverse(LCA);
curl = q[i].l,curr = q[i].r;
}
for (i = 1;i <= cntq;i++) write(ans[i]),putchar('\n');
return 0;
}

【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】糖果公园 [树上莫队]

    题意: 一棵树,修改一个点的颜色,询问两点路径上每种颜色的权值$val[c]$*出现次数的权值$cou[w[c]]$的和 sro VFK 树上莫队 按照王室联邦的方法分块,块的大小直径个数有保证,并不 ...

  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. java valid 注解使用-java validation注解详解

    注解 描述 @AssertFalse 带注解的元素必须为false,支持boolean/Boolean @AssertTrue 带注解的元素必须为true,支持boolean/Boolean @Dec ...

  2. TeamViewer如何绑定谷歌二次验证码/谷歌身份验证?

    1.下载TeamViewer,找到谷歌二次验证界面 下载.注册TeamViewer后,点击右上角账户名-“编辑配置文件” [常规]-“双重验证”,点“启用”   进入[激活双重验证]界面,点“启动激活 ...

  3. python读取hdfs上的parquet文件方式

    在使用python做大数据和机器学习处理过程中,首先需要读取hdfs数据,对于常用格式数据一般比较容易读取,parquet略微特殊.从hdfs上使用python获取parquet格式数据的方法(当然也 ...

  4. css的一些小技巧。修改input样式

    在第一次正式写项目的时候,遇到了几个布局的小技巧.记录一下. 我们常常会遇到图片和文字对齐的一种样式.比如 这样的样式,我们写的时候有时候会出现不对齐的情况.我们有俩种方法 一种就是flex的布局,还 ...

  5. 【Nginx】如何实现Nginx的高可用负载均衡?看完我也会了!!

    写在前面 不得不说,最近小伙伴们的学习热情是越来越高,不断向冰河提出新的想学习的技术.这不,又有小伙伴问我:冰河,你在[Nginx专题]写的文章基本上都是Nginx单机版的,能不能写一篇关于Nginx ...

  6. IO—》打印流&commons-IO

    打印流 打印流添加输出数据的功能,使它们能够方便地打印各种数据值表示形式. 打印流根据流的分类: 字节打印流 PrintStream 字符打印流 PrintWriter 方法: void print( ...

  7. URI(统一资源标识符)

    URI:统一资源标识符 (Uniform Resource Identifier) 统一资源标识符是一个用于标识某一互联网资源名称的字符串. Web上可用的每种资源 -HTML文档.图像.视频片段.程 ...

  8. Letex中表格问题

    最近在学习使用Letex,在学习过程中碰到很多小问题,故记之. 以下是一个参数表的实例(绘成三线表的形式). \begin{table}[hp] %%参数: h:放在此处 t:放在顶端 b:放在底端 ...

  9. Fortify Audit Workbench 笔记 Privacy Violation 隐私泄露

    Privacy Violation 隐私泄露 Abstract 对各种机密信息处理不当,如客户密码或社会保障号码,会危及到用户的个人隐私,这是一种非法行为. Explanation Privacy V ...

  10. 我是如何从零开始自学转行IT并进入世界500强实现薪资翻倍?

    本部分内容对应视频链接. 熟悉我的朋友应该知道,我本科及硕士期间所学的专业都是机械相关,毕业两年之后才从零开始自学转行成为一名程序员.当时我写了一篇文章,介绍我的转行经历,很多小伙伴因为我的这篇文章, ...