解法:我们先对每个节点的出边按儿子的编号排序,然后每个儿子都会得到一个顺序
k
k
k,将树重链剖分,每个点对应的
h
a
s
h
hash
hash值是重儿子顺序
k
∗
p
[
d
f
n
]
k*p[dfn]
k∗p[dfn],然后维护每条重链的
h
a
s
h
hash
hash值,同时用树状数组动态维护
a
a
a序列
h
a
s
h
hash
hash值,每次查询操作,我们从
x
x
x节点,顺着它的重链通过hash二分找到其与
a
a
a序列的
l
c
p
lcp
lcp,然后我们跳到
l
c
p
lcp
lcp的那个节点继续操作即可。明天再试试线段树解法
#include<bits/stdc++.h>#define ll long long#define ull unsigned long long#define low(x) x&-x
using namespace std;constint maxn =5e5+10, base =998244353;
ull p[maxn];
vector<int> G[maxn];int a[maxn], sz[maxn], son[maxn], pos[maxn], cnt;int id[maxn], rk[maxn], f[maxn], bot[maxn], n;struct HASH {
ull c[maxn];voidup(int x, ull v){
v *= p[x];for(; x <= n; x +=low(x))
c[x]+= v;}
ull qu(int x){
ull res =0;for(; x; x -=low(x))
res += c[x];return res;}
ull query(int l,int r){
ll res =qu(r)-qu(l -1);return res * p[n - l];}} T1, T2;voiddfs1(int u,int fa){
sz[u]=1;
f[u]= fa;sort(G[u].begin(), G[u].end());int i =0;for(auto v : G[u]){dfs1(v, u);
sz[u]+= sz[v];++i;if(sz[son[u]]< sz[v])
son[u]= v, pos[u]= i;}}voiddfs2(int u,int top){
id[u]=++cnt;
rk[cnt]= u;if(!son[u]){
bot[u]= u;
T1.up(id[u],-9102);return;}else{dfs2(son[u], top);
bot[u]= bot[son[u]];}
T1.up(id[u], pos[u]);for(auto v : G[u])if(v != son[u])dfs2(v, v);}intlcp(int l1,int r1,int l2,int r2){int L =0, R =min(r1 - l1 +1, r2 - l2 +1);while(L < R){int m =(L + R)/2;if(T1.query(l1, l1 + m)!= T2.query(l2, l2 + m))
R = m;else
L = m +1;}return L;}intgao(int x,int l,int r){int L = id[x], R = id[bot[x]];while(l <= r){int k =lcp(L, R, l, r);
l += k;int o = rk[L + k];if(l > r || a[l]> G[o].size())return o;
x = G[o][a[l]-1];
l++;if(l > r)return x;
L = id[x];
R = id[bot[x]];}}intmain(){
p[0]=1;for(int i =1; i < maxn; i++)
p[i]= p[i -1]* base;int m, q, l, r, opt, x, rt;scanf("%d%d%d",&n,&m,&q);for(int i =1; i <= n; i++){scanf("%d",&x);if(x)
G[x].push_back(i);else
rt = i;}for(int i =1; i <= m; i++){scanf("%d",&a[i]);
T2.up(i, a[i]);}dfs1(rt,0);dfs2(rt, rt);while(q--){scanf("%d",&opt);if(opt ==1){scanf("%d%d%d",&x,&l,&r);printf("%d\n",gao(x, l, r));}else{scanf("%d%d",&l,&x);
T2.up(l, x - a[l]);
a[l]= x;}}}
C. 【XR-3】核心城市 树直径签到题#include<bits/stdc++.h>using namespace std;const int maxn = 1e5 + 10;vector<int> G[maxn];int dep[maxn], rt, o, dp[maxn];void dfs(int u, int fa) { dep[u] = ...