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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【树链剖分】Milk Visits G(luogu 5838)

發布時間:2023/12/3 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【树链剖分】Milk Visits G(luogu 5838) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

luogu 5838


題目大意

給你一棵樹,和若干查詢,每次查詢一條路徑上是否有點的權值為x


解題思路

離線處理,每次將樹上權值為x的點附上1的值,然后詢問就是求和,查詢完后清零


代碼

#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 100010 using namespace std; int n, m, x, y, w, g, gg, tot, s[N], v[N], hs[N], fa[N], ans[N], dep[N], anc[N], head[N]; struct rec {int to, next; }a[N<<1]; struct node {int x, v;bool operator < (const node b) const{return x < b.x;} }pt[N]; struct nodee {int t, x, y, v;bool operator < (const nodee b) const{return t < b.t;} }q[N]; struct Tree//線段樹求和 {int a[N<<2];#define ls x*2#define rs x*2+1void up(int x){a[x] = a[ls] + a[rs];return;}void add(int x, int L, int R, int w, int s){if (L == w && w == R){a[x] += s;return;}int mid = L + R >> 1;if (w <= mid) add(ls, L, mid, w, s);else add(rs, mid + 1, R, w, s);up(x);}int ask(int x, int L, int R, int l, int r){if (L == l && R == r) return a[x];int mid = L + R >> 1;if (r <= mid) return ask(ls, L, mid, l, r);if (l > mid) return ask(rs, mid + 1, R, l, r);return ask(ls, L, mid, l, mid) + ask(rs, mid + 1, R, mid + 1, r);} }T; void add(int x, int y) {a[++tot].to = y;a[tot].next = head[x];head[x] = tot;return; } void dfs1(int x) {s[x] = 1;for (int i = head[x]; i; i = a[i].next)if (a[i].to != fa[x]){fa[a[i].to] = x;dep[a[i].to] = dep[x] + 1;dfs1(a[i].to);s[x] += s[a[i].to];if (s[a[i].to] > s[hs[x]]) hs[x] = a[i].to;}return; } void dfs2(int x, int y) {anc[x] = y;v[x] = ++w;if (hs[x]) dfs2(hs[x], y);for (int i = head[x]; i; i = a[i].next)if (a[i].to != fa[x] && a[i].to != hs[x])dfs2(a[i].to, a[i].to); } int ask(int x, int y)//求和 {int g = 0;while (anc[x] != anc[y]){if (dep[anc[x]] < dep[anc[y]]) swap(x, y);g += T.ask(1, 1, n, v[anc[x]], v[x]);x = fa[anc[x]];}if (dep[x] > dep[y]) swap(x, y);g += T.ask(1, 1, n, v[x], v[y]);return g; } int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= n; ++i){scanf("%d", &pt[i].x);pt[i].v = i;}for (int i = 1; i < n; ++i){scanf("%d%d", &x, &y);add(x, y);add(y, x);}for (int i = 1; i <= m; ++i){scanf("%d%d%d", &q[i].x, &q[i].y, &q[i].t);q[i].v = i;}sort(pt + 1, pt + 1 + n);sort(q + 1, q + 1 + m);fa[1] = dep[1] = 1;dfs1(1);dfs2(1, 1);g = 1;gg = 1;while(g <= n){int h = g;while(pt[h].x == pt[g].x && h <= n) T.add(1, 1, n, v[pt[h].v], 1), h++;//賦值點權while(q[gg].t < pt[g].x && gg <= m) gg++;//沒有該權值的點while(q[gg].t == pt[g].x && gg <= m) ans[q[gg].v] = ask(q[gg].x, q[gg].y), gg++;//查詢for (int i = g; i < h; ++i)T.add(1, 1, n, v[pt[i].v], -1);g = h;}for (int i = 1; i <= m; ++i)if (ans[i]) putchar('1');else putchar('0');return 0; }

總結

以上是生活随笔為你收集整理的【树链剖分】Milk Visits G(luogu 5838)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。