有一棵n
nn個點的樹。
有m
mm個人,第i
ii個人從x
ix_i
xi開始,以每秒1條邊的速度向y
iy_i
yi跑。
每個點有乙個觀察員在第t
it_i
ti秒觀察,求每個點的觀察員能觀察到幾個人。
首先把一條路拆成向上和向下的兩條,分別考慮。
向上的路徑,如果能對x
xx產生貢獻,必須滿足:
1.stst向下的路徑,如果能對xst在x
xx的子樹裡
2.e ded
ed在x
xx的外部(實際上就是在x
xx到根的鏈上)
3.d pt
[st]
=dpt
[x]+
t[x]
dpt[st]=dpt[x]+t[x]
dpt[st
]=dp
t[x]
+t[x
](dp
tdpt
dpt表示深度,stst
st表示路徑的起點,eded
ed表示終點)
xx產生貢獻,必須滿足:
1.eded發現條件有點多,比較難處理。首先我想的是線段樹合併(並沒有a掉,而且現在還不知道錯在**)。ed在x
xx的子樹裡
2.s tst
st在x
xx的外部(實際上就是在x
xx到根的鏈上)
3.d pt
[st]
−t1[
st]=
dpt[
x]−t
[x
]dpt[st]-t1[st]=dpt[x]-t[x]
dpt[st
]−t1
[st]
=dpt
[x]−
t[x]
(t 1t1
t1表示出發時間,因為可能接在向上的路徑之後)
每個點一棵權值線段樹,存向上路徑的dpt
[st]
dpt[st]
dpt[st
]數量和向下路徑的dpt
[st]
−t1[
st
]dpt[st]-t1[st]
dpt[st
]−t1
[st]
數量,在較深的點+1,在較淺的點的上方-1。動態開點,時間空間複雜度其實都沒有問題,但是又re又wa不知道為什麼。
然後此時看到了題解中的差分+桶。
其實桶比線段樹多存的就是較深的點的dfn在當前點之前,較淺的點卻還沒有被退棧的路徑,換句話說就是在當前子樹之外,卻還在桶內的點。最開始因為不知道如何處理這個所以沒有繼續想下去。
然後此時又在茫茫題解中看到了chy神仙的題解。
只要在當前節點剛剛入棧的時候記錄一下當前桶裡的值,後來再減掉就好了。
太精闢了喂。可能這就是神仙吧。非常簡單但是很厲害。
#include
#define pb push_back
using
namespace std;
const
int n =
3e5+10;
const
int m = n<<1;
const
int e =20;
int n, m, tim[n]
;struct g
void
add(
int u,
int v)
}g;int dpt[n]
, f[n]
[e];
vector<
int> st1[n]
, ed1[n]
, st2[n]
, ed2[n]
;int ton1[n<<1]
, ton2[n<<1]
, ans[n]
;void
dfs(
int u,
int fa)
}int
lca(
int x,
int y)
intson
(int x,
int y)
void
dfs1
(int u,
int fa)
ans[u]
= ton1[dpt[u]
+tim[u]
]+ton2[dpt[u]
-tim[u]
+n]-tmp;
for(
int i =
0, ub = ed1[u]
.size()
; i < ub;
++ i)
-- ton1[ed1[u]
[i]]
;for
(int i =
0, ub = ed2[u]
.size()
; i < ub;
++ i)
-- ton2[ed2[u]
[i]];}
intmain()
dpt[0]
=-1;
dfs(1,
0);for
(int i =
1; i <= n;
++ i)
scanf
("%d"
,&tim[i]);
for(
int i =
1; i <= m;
++ i)
}memset
(ans,0,
sizeof
(ans));
memset
(ton1,0,
sizeof
(ton1));
memset
(ton2,0,
sizeof
(ton2));
dfs1(1
,0);
for(
int i =
1; i <= n;
++ i)
printf
("%d "
, ans[i]);
return0;
}
NOIP2016 天天愛跑步
時間限制 2 s 記憶體限制 512 mb 題目描述 小c同學認為跑步非常有趣,於是決定製作一款叫做 天天愛跑步 的遊戲。天天愛跑步 是乙個養成類遊戲,需要玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一棵包含n個結點和n 1條邊的樹,每條邊連線兩個結點,且任意兩個結點存在一條路徑互相可達。...
NOIP2016天天愛跑步
小c同學認為跑步非常有趣,於是決定製作一款叫做 天天愛跑步 的遊戲。天天愛跑步 是乙個養成類遊戲,需要玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一一棵包含 nn n個結點和 n 1n 1n 1條邊的樹,每條邊連線兩個結點,且任意兩個結點存在一條路徑互相可達。樹上結點編號為從11 1到nn...
NOIP2016 天天愛跑步
看這道題不爽很久了,但一直沒有開它,原因是我不會 我太菜了 看了題解還是寫不來,因為我不會線段樹合併。然後今天學了dsu on tree這種神奇的科技,成功把它a了,效率吊打線段樹合併。於是寫篇題解紀念一下。洛谷p1600 天天愛跑步 不帶修改的樹上路徑資訊的維護,很容易想到樹上差分。我們考慮一條路...