NOIP2016 T2 天天愛跑步

2021-08-04 11:55:38 字數 1205 閱讀 6571

我們思考一下從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...