日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

B. Alyona and a tree(dsu on tree + bit)

發(fā)布時間:2023/12/4 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 B. Alyona and a tree(dsu on tree + bit) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

B. Alyona and a tree(dsu on tree + bit)

給定一顆以111號節(jié)點為根的樹,每個點有點權(quán)aia_iai?,邊有邊權(quán),如果vvv控制了點uuu,當且僅當uuuvvv的子樹中的節(jié)點且dis(u,v)≤audis(u, v) \leq a_udis(u,v)au?

我們定義d(u)d(u)d(u)為點111到點uuu距離,則對于某個點vvv來說我們就是要在其字數(shù)上找d(u)?d(v)≤aud(u) - d(v) \leq a_ud(u)?d(v)au?d(u)?au≤d(v)d(u) - a_u \leq d(v)d(u)?au?d(v),

對所有的d(u)?au,d(u)d(u) - a_u, d(u)d(u)?au?,d(u)進行離散化,就可以考慮樹上啟發(fā)式合并 + 樹狀數(shù)組來完成上述操作,整體復雜度O(nlog?nlog?n)O (n \log n \log n)O(nlognlogn)

#include <bits/stdc++.h>using namespace std;const int N = 2e5 + 10;int head[N], to[N], nex[N], value[N], cnt = 1;int a[N], ans[N], sz[N], son[N], l[N], r[N], id[N], sum[N << 3], tot, n, m;long long d[N], b[N << 1];inline int lowbit(int x) {return x & -x; }void add(int x, int y, int w) {to[cnt] = y;nex[cnt] = head[x];value[cnt] = w;head[x] = cnt++; }void dfs(int rt, int fa) {sz[rt] = 1, l[rt] = ++tot, id[tot] = rt;for (int i = head[rt]; i; i = nex[i]) {if (to[i] == fa) {continue;}d[to[i]] = d[rt] + value[i];dfs(to[i], rt);sz[rt] += sz[to[i]];if (!son[rt] || sz[to[i]] > sz[son[rt]]) {son[rt] = to[i];}}r[rt] = tot; }void update(int x, int v) {while (x <= m) {sum[x] += v;x += lowbit(x);} }int query(int x) {int ans = 0;while (x) {ans += sum[x];x -= lowbit(x);}return ans; }void dfs(int rt, int fa, bool keep) {for (int i = head[rt]; i; i = nex[i]) {if (to[i] == fa || to[i] == son[rt]) {continue;}dfs(to[i], rt, 0);}if (son[rt]) {dfs(son[rt], rt, 1);}for (int i = head[rt]; i; i = nex[i]) {if (to[i] == fa || to[i] == son[rt]) {continue;}for (int j = l[to[i]]; j <= r[to[i]]; j++) {update(d[id[j]], 1);}}ans[rt] = query(a[rt]);update(d[rt], 1);if (!keep) {for (int i = l[rt]; i <= r[rt]; i++) {update(d[id[i]], -1);}} }int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d", &n);for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);}for (int i = 2, x, w; i <= n; i++) {scanf("%d %d", &x, &w);add(x, i, w);}dfs(1, 0);for (int i = 1; i <= n; i++) {b[++m] = d[i], b[++m] = d[i] - a[i];}sort(b + 1, b + 1 + m);m = unique(b + 1, b + 1 + m) - (b + 1);for (int i = 1; i <= n; i++) {int temp = a[i];a[i] = lower_bound(b + 1, b + 1 + m, d[i]) - b;d[i] = lower_bound(b + 1, b + 1 + m, d[i] - temp) - b;}dfs(1, 0, 1);for (int i = 1; i <= n; i++) {printf("%d%c", ans[i], i == n ? '\n' : ' ');}return 0; }

總結(jié)

以上是生活随笔為你收集整理的B. Alyona and a tree(dsu on tree + bit)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。