【WC2013】糖果公园

UOJ

题解:树上莫队转移。

一开始UV打错,WA了一发。

  1 #include<cmath>
  2 #include<cstdio>
  3 #include<iostream>
  4 #include<vector>
  5 #include<algorithm>
  6 #define pb push_back
  7 using namespace std;
  8 inline char nc() {
  9     static char b[1<<14],*s=b,*t=b;
 10     return s==t&&(t=(s=b)+fread(b,1,1<<14,stdin),s==t)?-1:*s++;
 11 }
 12 inline void read(int &x) {
 13     char b = nc(); x = 0;
 14     for (; !isdigit(b); b = nc());
 15     for (; isdigit(b); b = nc()) x = x * 10 + b - ‘0‘;
 16 }
 17 typedef long long ll;
 18 const int N = 100010;
 19 int n, m, QQ, val[N], w[N], a[N], ta[N];
 20 ll tans, ans[N];
 21 vector < int > g[N];
 22 inline void ae(int u, int v) {
 23     g[u].pb(v); g[v].pb(u);
 24 }
 25 int sz[N], fa[N], dep[N], son[N], top[N];
 26 int I[N], O[N], f[N*2], D, S, bl[N*2];
 27 int U[N], V[N], T, qq, P[N];
 28 void dfs1(int u, int f) {
 29     sz[u] = 1; fa[u] = f; dep[u] = dep[f] + 1;
 30     for (int i = 0, v; i < g[u].size(); ++i) if ((v = g[u][i]) != f) {
 31         dfs1(v, u); sz[u] += sz[v]; if (sz[son[u]] < sz[v]) son[u] = v;
 32     }
 33 }
 34 void dfs2(int u, int tp) {
 35     I[u] = ++D; f[D] = u;
 36     top[u] = tp; if (son[u]) dfs2(son[u], tp);
 37     for (int i = 0, v; i < g[u].size(); ++i)
 38         if (v = g[u][i], v != fa[u] && v != son[u]) dfs2(v, v);
 39     O[u] = ++D; f[D] = u;
 40 }
 41 inline int findLca(int a, int b) {
 42     for (; top[a] != top[b]; a = fa[top[a]])
 43         if (dep[top[a]] < dep[top[b]]) swap(a, b);
 44     return dep[a] < dep[b] ? a : b;
 45 }
 46 struct Q {
 47     int l, r, e, t, id;
 48     inline void init(int u, int v, int i) {
 49         id = i; e = findLca(u, v); t = T;
 50         if (I[u] > I[v]) swap(u, v);
 51         if (u == e) e = 0, l = I[u], r = I[v];
 52         else l = O[u], r = I[v];
 53         if (l > r) swap(l, r);
 54     }
 55     inline bool operator<(const Q &q) const {
 56         if (bl[l] != bl[q.l]) return bl[l] < bl[q.l];
 57         if (r != q.r) return r < q.r; return t < q.t;
 58     }
 59 } q[N];
 60 int cn[N], cnt[N];
 61 inline void addc(int c) {
 62     tans += val[c] * 1ll * w[++cnt[c]];
 63 }
 64 inline void delc(int c) {
 65     tans -= val[c] * 1ll * w[cnt[c]--];
 66 }
 67 inline void addn(int u) {
 68     ++cn[u] == 1 ? addc(a[u]) : delc(a[u]);
 69 }
 70 inline void deln(int u) {
 71     --cn[u] == 1 ? addc(a[u]) : delc(a[u]);
 72 }
 73 inline void edt(int u, int x) {
 74     if ((cn[u] += x) == 1) addc(a[u]); else delc(a[u]);
 75 }
 76 inline void addt(int t) {
 77     if (cn[P[t]] == 1)
 78         addc(V[t]), delc(U[t]);
 79     a[P[t]] = V[t];
 80 }
 81 inline void delt(int t) {
 82     if (cn[P[t]] == 1)
 83         addc(U[t]), delc(V[t]);
 84     a[P[t]] = U[t];
 85 }
 86 void solve() {
 87     for (int i = 1, l = 1, r = 0, t = 0; i <= qq; ++i) {
 88         while (t < q[i].t) addt(++t);
 89         while (t > q[i].t) delt(t--);
 90         while (r < q[i].r) addn(f[++r]);
 91         while (r > q[i].r) deln(f[r--]);
 92         while (l < q[i].l) deln(f[l++]);
 93         while (l > q[i].l) addn(f[--l]);
 94         if (q[i].e) addn(q[i].e);
 95         ans[q[i].id] = tans;
 96         if (q[i].e) deln(q[i].e);
 97     }
 98 }
 99 int main() {
100     read(n), read(m), read(QQ); S = pow(n * 2, 0.5) + 1;
101     for (int i = 1; i <= m; ++i) read(val[i]);
102     for (int i = 1; i <= n; ++i) read(w[i]);
103     for (int i = 1; i <= n * 2; ++i) bl[i] = (i - 1) / S + 1;
104     for (int i = 1, u, v; i < n; ++i)
105         read(u), read(v), ae(u, v);
106     dfs1(1, 0); dfs2(1, 1);
107     for (int i = 1; i <= n; ++i) read(a[i]), ta[i] = a[i];
108     for (int op, u, v, i = 0; i < QQ; ++i) {
109         read(op); read(u); read(v);
110         if (op) ++qq, q[qq].init(u, v, qq);
111         else {
112             ++T; P[T] = u; U[T] = ta[u]; V[T] = v; ta[u] = v;
113         }
114     } sort(q + 1, q + 1 + qq); solve();
115     for (int i = 1; i <= qq; ++i) printf("%lld\n", ans[i]);
116     return 0;
117 }

原文地址:https://www.cnblogs.com/p0ny/p/8136325.html

时间: 2024-10-19 03:40:54

【WC2013】糖果公园的相关文章

WC2013 糖果公园

COGS 1817. [WC2013]糖果公园 http://www.cogs.pro/cogs/problem/problem.php?pid=1817 ★★★☆   输入文件:park.in   输出文件:park.out   简单对比时间限制:8 s   内存限制:512 MB [题目描述] Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园玩. 糖果公园的结构十分奇特,它由 n 个游览点构成,每个游览点

[bzoj 3052][wc2013]糖果公园

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3052 [wc2013]糖果公园 Time Limit: 200 Sec  Memory Limit: 512 MBSubmit: 1213  Solved: 609[Submit][Status][Discuss] Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 树上莫队,把树分块,

bzoj 3052: [wc2013]糖果公园 带修改莫队

3052: [wc2013]糖果公园 Time Limit: 250 Sec  Memory Limit: 512 MBSubmit: 506  Solved: 189[Submit][Status] Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 HINT 本来这道题想到了莫队算法,但是看到带修改就直接放弃了.结果看题解才发现带修改居然也能用莫队!!!之所以可以这样用,是因为修改的时间复

AC日记——[WC2013]糖果公园 cogs 1817

[WC2013]糖果公园 思路: 带修改树上莫队(模板): 来,上代码: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 100005 #define ll long long struct QueryType { ll u,v,t,id;

bzoj 3052: [wc2013]糖果公园(带修改的树上莫队)

3052: [wc2013]糖果公园 Time Limit: 200 Sec  Memory Limit: 512 MB Submit: 892  Solved: 425 [Submit][Status][Discuss] Description Input Output Sample Input Sample Input Sample Output 84 131 27 84 HINT Source [Submit][Status][Discuss] 题解:bzoj 2120 和 bzoj 37

【BZOJ】3052: [wc2013]糖果公园 树分块+待修改莫队算法

[题目]#58. [WC2013]糖果公园 [题意]给定n个点的树,m种糖果,每个点有糖果ci.给定n个数wi和m个数vi,第i颗糖果第j次品尝的价值是v(i)*w(j).q次询问一条链上每个点价值的和或修改一个点的糖果ci.n,m,q<=10^5. [算法]树分块+带修改莫队算法 [题解]参考:WC 2013 糖果公园 park 题解 by vfleaking 首先树分块,参考王室联邦的方法.确定块大小为B,一遍DFS可以分成若干大小为[B,3B]的块,性质是块内两点距离至多为B. 定义(x,

[BZOJ3052][UOJ#58][WC2013]糖果公园

试题描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园玩. 糖果公园的结构十分奇特,它由 n 个游览点构成,每个游览点都有一个糖果发放处,我们可以依次将游览点编号为 1 至 n.有 n?1 条双向道路连接着这些游览点,并且整个糖果公园都是连通的,即从任何一个游览点出发都可以通过这些道路到达公园里的所有其它游览点. 糖果公园所发放的糖果种类非常丰富,总共 m 种,它们的编号依次为 1 至 m.每一个糖果发放

【Luogu P4074】[WC2013]糖果公园(树上带修改莫队)

题目描述 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 \(n\) 个游览点构成,每个游览点都有一个糖果发放处,我们可以依次将游览点编号为 \(1\) 至 \(n\).有 \(n-1\) 条双向道路连接着这些游览点,并且整个糖果公园都是连通的,即从任何一个游览点出发都可以通过这些道路到达公园里的所有其它游览点. 糖果公园所发放的糖果种类非常丰富,总共有 \(m\) 种,

【uoj58】 WC2013—糖果公园

http://uoj.ac/problem/58 (题目链接) 题意:给定一棵树,每个点有一个颜色,提供两种操作:  1.询问两点间路径上的Σv[a[i]]*w[k],其中a[i]代表这个点的颜色,k表示这个点是这种颜色第k次出现  2.修改某个点的颜色 Solution  带修改树上莫队.  按左端点所在块为第一关键字,右端点所在块为第二关键字,时间为第三关键字,排序.可能会有疑问可不可以以右端点dfs序为第二关键字?这里我们为了突出第三关键字的作用,选择以右端点所在块为第二关键字.每个节点的

[UOJ #58][WC2013]糖果公园(树上带修改莫队)

Description Solution 树上带修改莫队…!VFK的题解写得很清楚啦 (我的程序为什么跑得这么慢…交的时候总有一种自己在卡测评的感觉…) #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #define MAXN 100005 typedef long l