題意:有一棵\(n\)個點的樹,有\(m\)個玩家,每個玩家有乙個起點\(s_i,t_i\),所有的玩家在第\(0\)秒從自己的起點出發,以每秒跑一條邊的速度,沿著最短路徑向終點跑。節點\(j\)的觀察員會在第\(w_j\)秒觀察此時該節點上的玩家,求每個觀察員會觀察到多少人?
題目鏈結
資料範圍:\(1<=n,m<=3e5\)
解法:\(lca\) + 桶 + 差分
先預處理出每個節點的深度\(dep_i\),以及每條路徑的長度\(dis_i\)(用倍增\(lca\))。
這裡我們如果考慮觀察員,會發現時間複雜度很難優化。所以我們考慮每個玩家對答案的貢獻。
我們先把每條路徑拆成向上的一段和向下的一段(最後的時候要注意起點和終點是否會對\(lca\)重複貢獻)
向上:考慮位於節點\(j\)的觀察員,當且僅當\(s_i\)位於\(j\)的子樹中且\(s_i,t_i\)的lca不在\(j\)之上時,如果\(dep_ = dep_j+w_j\),則\(s_i\)會對\(j\)產生貢獻。
向下同理,式子變為\(dis_i-(dep_-dep_j)=w_j\)時會對\(j\)產生貢獻。
我們用桶記錄,每次出乙個節點時用桶統計答案,並減掉這個點最為\(lca\)時對這個點以上的點的答案的影響。
#include#includeusing namespace std;
#define maxn 300100
int n, m;
int w[maxn], dep[maxn], dis[maxn];
int f1[maxn], f2[maxn * 2];
int st[maxn], ed[maxn], cnt[maxn], ans[maxn];
int f[maxn][22];
int fir[maxn], nxt[maxn * 2], vv[maxn * 2];
int fir1[maxn], nxt1[maxn * 2], vv1[maxn * 2];
int fir2[maxn], nxt2[maxn * 2], vv2[maxn * 2];
int tot, tot1, tot2;
void add(int u, int v)
void add1(int u, int v)
void add2(int u, int v)
void deal_first(int u, int fa)
return;
}int lca(int x, int y)
if(x == y)
}for(int i = 20; i >= 0; i--) }
return f[x][0];
}void dfs(int u, int fa)
f1[dep[u]] += cnt[u];//以u為起點
for(int i = fir1[u]; i; i = nxt1[i])// 列舉以u為終點的情況 因為每個終點的dis值不同,故須記錄乙個鏈式前向星
ans[u] += (f1[w[u] + dep[u]] - tmp1) + (f2[w[u] - dep[u] + maxn] - tmp2);
for(int i = fir2[u]; i; i = nxt2[i])
return;
}int main()
for(int i = 1; i <= n; i++) scanf("%d", &w[i]);
deal_first(1, 1); dep[1] = 1;// printf("makiah");
for(int i = 1; i <= m; i++)
dfs(1, 0);
for(int i = 1; i <= n; i++) printf("%d ", ans[i]);
return 0;
}
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 天天愛跑步 不帶修改的樹上路徑資訊的維護,很容易想到樹上差分。我們考慮一條路...