我們思考一下從x到y的路徑,這個可以拆成從x到lca的路徑和從lca到y的路徑,這個很明顯。
如果乙個點i在從x到lca 的路徑可以檢測到的話,那麼就有deep[i]+w[i]=deep[x]。
如果乙個點i在從lca到y的路徑上可以檢測到的話,那麼就有deep[i]-w[i]=deep[y]-t(t表示x到y的路徑長度)。
對於每個點i,我們已知deep[i],w[i],只需要在路徑上標上等號左側的數字。
考慮樹上差分,將問題轉化為子樹集問題。
dfs維護兩個桶,乙個向上的桶a和乙個向下的桶b(分別表示deep[x],deep[y]-t)。
每次ans[x]的答案就是子樹a[deep[x]+w[x]]+b[deep[x]-w[x]]的數量。
由於乙個子樹中節點的dfs序是一段連續的區間,答案用進入該節點時候的值減去出節點即可。
時間複雜度o(
n)
#include
#include
#include
#include
#include
#include
using
namespace
std;
int getint()
const
int n=3e5+5;
int n,m,tot;
int w[n],cnt[n<<2],ans[n];
int dep[n],fa[n][25];
int first[n],next[n<<1],to[n<<1];
struct node
node(int _dep,int _f):
dep(_dep),f(_f){}
};vector
pos[n];
void add(int x,int y)
inline
void dfs(int u,int f)
}}int lca(int x,int y)
inline
void solve(int u)
ans[u]=cnt[dep[u]+w[u]]+cnt[w[u]-dep[u]+3*n+1]-res;
}int main()
solve(1);
for(int i=1;i<=n;i++)
cout
<" ";
return
0;}
NOIP2016 DAY1T2 天天愛跑步
描述 小c同學認為跑步非常有趣,於是決定製作一款叫做 天天愛跑步 的遊戲。天天愛跑步 是乙個養成類遊戲,需要玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一棵包含n個結點和n 1條邊的樹,每條邊連線兩個結點,且任意兩個結點存在一條路徑互相可達。樹上結點編號為從1到n的連續正整數。現在有m個玩...
NOIP2016 天天愛跑步
時間限制 2 s 記憶體限制 512 mb 題目描述 小c同學認為跑步非常有趣,於是決定製作一款叫做 天天愛跑步 的遊戲。天天愛跑步 是乙個養成類遊戲,需要玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一棵包含n個結點和n 1條邊的樹,每條邊連線兩個結點,且任意兩個結點存在一條路徑互相可達。...
NOIP2016天天愛跑步
小c同學認為跑步非常有趣,於是決定製作一款叫做 天天愛跑步 的遊戲。天天愛跑步 是乙個養成類遊戲,需要玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一一棵包含 nn n個結點和 n 1n 1n 1條邊的樹,每條邊連線兩個結點,且任意兩個結點存在一條路徑互相可達。樹上結點編號為從11 1到nn...