小c同學認為跑步非常有趣,於是決定製作一款叫做《天天愛跑步》的遊戲。?天天愛跑步?是乙個養成類遊戲,需要
玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一一棵包含 n個結點和n-1 條邊的樹, 每條邊連線兩
個結點,且任意兩個結點存在一條路徑互相可達。樹上結點編號為從1到n的連續正整數。現在有個玩家,第個玩家的
起點為si ,終點為ti 。每天打卡任務開始時,所有玩家在第0秒同時從自己的起點出發, 以每秒跑一條邊的速度,
不間斷地沿著最短路徑向著自己的終點跑去, 跑到終點後該玩家就算完成了打卡任務。 (由於地圖是一棵樹, 所以
每個人的路徑是唯一的)小c想知道遊戲的活躍度, 所以在每個結點上都放置了乙個觀察員。 在結點的觀察員會選
擇在第wj秒觀察玩家, 乙個玩家能被這個觀察員觀察到當且僅當該玩家在第wj秒也理到達了結點j 。 小c想知道
每個觀察員會觀察到多少人?注意: 我們認為乙個玩家到達自己的終點後該玩家就會結束遊戲, 他不能等待一 段時
間後再被觀察員觀察到。 即對於把結點j作為終點的玩家: 若他在第wj秒重到達終點,則在結點j的觀察員不能觀察
到該玩家;若他正好在第wj秒到達終點,則在結點的觀察員可以觀察到這個玩家。
第一行有兩個整數n和m 。其中n代表樹的結點數量, 同時也是觀察員的數量, m代表玩家的數量。
接下來n-1 行每行兩個整數u和v ,表示結點u 到結點v 有一條邊。
接下來一行n 個整數,其中第個整數為wj , 表示結點出現觀察員的時間。
接下來 m行,每行兩個整數si和ti,表示乙個玩家的起點和終點。
對於所有的資料,保證 。
1<=si,ti<=n,0<=wj<=n n<=300000
輸出1行n 個整數,第個整數表示結點的觀察員可以觀察到多少人。
6 32 3
1 2
1 4
4 5
4 6
0 2 5 1 2 3
1 5
1 3
2 6
1 2 1 0 1
對於1號點,wi=0,故只有起點為1號點的玩家才會被觀察到,所以玩家1和玩家2被觀察到,共有2人被觀察到。
對於2號點,沒有玩家在第2秒時在此結點,共0人被觀察到。
對於3號點,沒有玩家在第5秒時在此結點,共0人被觀察到。
對於4號點,玩家1被觀察到,共1人被觀察到。
對於5號點,玩家1被觀察到,共1人被觀察到。
對於6號點,玩家3被觀察到,共1人被觀察到。
當時在考場上只打了25分的暴力,太弱了……現在回來補一補吧。
我們可以按照dfs的順序來計算每個點的答案,可以發現,如果一條鏈i對當前點u有貢獻,當且僅當①起點s[i]在u的子樹中 終點t[i]在u的子樹外 而且
deep[s[i]] - deep[u] == w[u] ②終點t[i]在u的子樹中 起點s[i]在u的子樹外 而且deep[t[i]]-deep[u] == len[i] - w[u] ③起點s[i]]和終點t[i]都在u的子樹中且lca(s[i],t[i])==u
於是我們可以記錄乙個關於深度的陣列d記錄當前有哪些鏈的端點需要考慮
這些東西都可以通過把鏈拆分成標記來解決,(pos,c)表示在pos處加上c ,c=1 或 -1
所以可以先做一次dfs求出每一對s和t的lca以及每個節點的深度
然後將每一條鏈拆成4個標記,s[i] -> (deep[s[i]],1) t[i]->(deep[t[i]]-len[i]) lca[i]->(deep[s[i]],-1) fa[lca[i]]->(deep[t[i]],-1)
再跑一次dfs就好了
然後就是有一些細節 比如w[u]==0的時候答案會被統計兩次,所以要/=2
複雜度o(nα(n)+m)
#include #include #include #include #include #include using namespace std;
typedef pairpii;
struct tag;
};const int n=600010;
int n,m,d[4*n];
int s[n],t[n],lca[n],w[n],ans[n];
int ihead[n],to[n*2],inext[2*n],cnt,f[n],fa[n],dep[n];
vectorg[n];
vectort[n];
inline int getint()
void addedge(int u,int v)
int father(int x)
void tarjan(int u)
} for (int i=0;i
BZOJ4719 Noip2016 天天愛跑步
考慮鏈上做法,發現就是把每個路徑拆成一次加入和一次刪除,然後從前往後掃,走一步所有路徑經過當前點的時間就要麼加一,要麼減一,且要麼是一直加一,要麼是一直減一,可以用兩個陣列和指標來維護整體加減 用鏈剖把乙個區間轉換成o log n 個區間,即可在樹上做 include include include...
NOIP2016 bzoj4719天天愛跑步
小c同學認為跑步非常有趣,於是決定製作一款叫做 天天愛跑步 的遊戲。天天愛跑步 是乙個養成類遊戲,需要玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一一棵包含 n n個結點和 n 1n 1條邊的樹,每條邊連線兩個結點,且任意兩個結點存在一條路徑互相可達。樹上結點編號為從11到n n的連續正整...
bzoj4719 Noip2016 天天愛跑步
description 小c同學認為跑步非常有趣,於是決定製作一款叫做 天天愛跑步 的遊戲。天天愛跑步?是乙個養成類遊戲,需要 玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一一棵包含 n個結點和n 1 條邊的樹,每條邊連線兩 個結點,且任意兩個結點存在一條路徑互相可達。樹上結點編號為從1到...