hdu 5840 This world need more Zhu (sqrt+树剖)

    xiaoxiao2025-08-06  2

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <queue> #include <map> #include <set> #include <algorithm> #include <ctime> #include <cstdlib> #include <functional> #include <bitset> using namespace std; #define eps 1e-10 #define N 200020 #define M 200020 #define mod 772002 #define G 3 #define inf 0x3f3f3f3f #define LL long long #define pii pair<int, int> #define MP make_pair #define fi first #define se second #define ls (i << 1) #define rs (ls | 1) #define md (ll + rr >> 1) #define lson ll, md, ls #define rson md + 1, rr, rs #define ui unsigned int char buf[32000000],*pt = buf,*o = buf; int getint(){ int f = 1,x = 0; while((*pt != '-') && (*pt < '0' || *pt > '9')) pt ++; if(*pt == '-') f = -1,pt ++; else x = *pt++ - 48; while(*pt >= '0' && *pt <= '9') x = x * 10 + *pt ++ - 48; return x * f; } char getch(){ char ch; while(*pt < 'A' || *pt > 'Z') pt ++; ch=*pt;pt++; return ch; } int n, q, fst[N], nxt[M], vv[M], e; int a[N]; int B; void init() { memset(fst, -1, sizeof fst); e = 0; } void add(int u, int v) { vv[e] = v, nxt[e] = fst[u], fst[u] = e++; } int fa[N], dep[N], sz[N], son[N]; int tp[N]; int st[N], ed[N], lab[N], dc; int ans[N]; int pos[N], num[N]; int mx[N << 2]; int L[N], R[N]; struct node { int u, p, b, k, id; node() {} node(int u, int p, int b, int k, int id): u(u), p(p), b(b), k(k), id(id) {} bool operator < (const node &vt) const { if(k != vt.k) return k < vt.k; return b < vt.b; } }p[2 * N]; int tot; void dfs1(int u, int p, int d) { dep[u] = d; fa[u] = p; sz[u] = 1; son[u] = 0; int mx = 0; for(int i = fst[u]; ~i; i = nxt[i]) { int v = vv[i]; if(v == p) continue; dfs1(v, u, d + 1); sz[u] += sz[v]; if(sz[v] > mx) son[u] = v, mx = sz[v]; } } void dfs2(int u, int anc) { tp[u] = anc; st[u] = ++dc; lab[dc] = u; if(son[u]) dfs2(son[u], anc); for(int i = fst[u]; ~i; i = nxt[i]) { int v = vv[i]; if(v == fa[u] || v == son[u]) continue; dfs2(v, v); } ed[u] = dc; } int lca(int u, int v) { while(tp[u] != tp[v]) { if(dep[tp[u]] > dep[tp[v]]) swap(u, v); v = fa[tp[v]]; } if(dep[u] > dep[v]) swap(u, v); return u; } int kfa(int u, int k) { while(1) { if(dep[u] - dep[tp[u]] < k) { if(tp[u] == 1) return 0; k -= dep[u] - dep[tp[u]] + 1; u = fa[tp[u]]; } else { return lab[st[u]-k]; } } } int bf_query(int u, int p, int k, int b) { int t = ((dep[u] - b) % k + k) % k; u = kfa(u, t); int ret = 0; while(u && dep[u] >= dep[p]) { ret = max(ret, a[u]); u = kfa(u, k); } return ret; } void build(int ll, int rr, int i) { if(ll == rr) { mx[i] = a[lab[pos[ll]]]; return; } build(lson); build(rson); mx[i] = max(mx[ls], mx[rs]); } int query(int l, int r, int ll, int rr, int i) { if(ll == l && rr == r) return mx[i]; if(r <= md) return query(l, r, lson); if(l > md) return query(l, r, rson); return max(query(l, md, lson), query(md + 1, r, rson)); } int calc_query(node x) { int b = x.b; if(L[b] == -1) return 0; int u = x.u; int p = x.p; int ret = 0; while(tp[u] != tp[p]) { int l = st[tp[u]], r = st[u]; l = lower_bound(pos + L[b], pos + R[b] + 1, l) - pos; r = upper_bound(pos + L[b], pos + R[b] + 1, r) - pos - 1; if(l <= r) ret = max(ret, query(l, r, 1, n, 1)); u = fa[tp[u]]; } int l = st[p], r = st[u]; l = lower_bound(pos + L[b], pos + R[b] + 1, l) - pos; r = upper_bound(pos + L[b], pos + R[b] + 1, r) - pos - 1; if(l <= r) ret = max(ret, query(l, r, 1, n, 1)); return ret; } int main() { int cas, kk = 0; scanf("%d", &cas); while(cas--) { scanf("%d%d", &n, &q); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); B = sqrt(n + 0.5); init(); for(int i = 1; i < n; ++i) { int u, v; scanf("%d%d", &u, &v); add(u, v); add(v, u); } dc = 0; dfs1(1, 0, 0); dfs2(1, 1); tot = 0; for(int i = 1; i <= q; ++i) { ans[i] = 0; int u, v, k; scanf("%d%d%d", &u, &v, &k); int fa = lca(u, v); int a = (dep[u] + 1) % k; int b = ((2 * dep[fa] - dep[u] - 1) % k + k) % k; if(k > B) { ans[i] = max(ans[i], bf_query(u, fa, k, a)); ans[i] = max(ans[i], bf_query(v, fa, k, b)); } else { p[++tot] = node(u, fa, a, k, i); p[++tot] = node(v, fa, b, k, i); } } sort(p + 1, p + tot + 1); for(int i = 1, j; i <= tot; i = j + 1) { j = i; while(j + 1 <= tot && p[i].k == p[j+1].k) ++j; int k = p[i].k; for(int u = 0; u < k; ++u) num[u] = 0, L[u] = R[u] = -1; for(int u = 1; u <= n; ++u) num[dep[lab[u]]%k]++; for(int u = 1; u < k; ++u) num[u] += num[u-1]; for(int u = n; u >= 1; --u) pos[num[dep[lab[u]]%k]--] = u; for(int u = 1, v; u <= n; u = v + 1) { v = u; while(v + 1 <= n && dep[lab[pos[u]]] % k == dep[lab[pos[v+1]]] % k) ++v; L[dep[lab[pos[u]]]%k] = u; R[dep[lab[pos[u]]]%k] = v; } build(1, n, 1); for(int u = i; u <= j; ++u) { ans[p[u].id] = max(ans[p[u].id], calc_query(p[u])); } } printf("Case #%d:\n", ++kk); for(int i = 1; i <= q; ++i) { printf("%d\n", ans[i]); } } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-1301474.html
    最新回复(0)