luogu P1600 天天愛跑步

2022-02-05 04:40:35 字數 1438 閱讀 4429

傳送門

1a此題暴祭

(下面記點\(x\)深度為\(de_x\),某個時間點記為\(w_x\))

首先,每條路徑是可以拆成往上和往下兩條路徑的

對於往上的路徑,假設有個人往上跑,\(w_y\)在點\(y\),那麼如果能對點\(x\)的觀察員產生貢獻,當且僅當\(w_x+de_x=w_y+de_y\)

對於往下的路徑,假設有個人往下跑,\(w_y\)在點\(y\),那麼如果能對點\(x\)的觀察員產生貢獻,當且僅當\(w_x-de_x=w_y-de_y\)

所以對於每個點開兩個線段樹,每個下表存\(w_x+de_x\)或\(w_x-de_x\)的點的個數,對於每條路徑(x,y),記\(len\)為路徑長度(結束時間點),\(mid\)為到達\(lca\)的時間,在\(x\)的第乙個線段樹的\(de_x\)處+1,在\(lca\)的第乙個線段樹的\(mid+de_\)處-1,在y的第二個線段樹的\(len-de_y+n\)處+1,在\(fa_\)的第二個線段樹的\(mid-1-de_}+n\)處-1(不能出現負下標).dfs整棵樹,把\(x\)所有兒子的線段樹並起來,然後這個點的答案就是第一棵線段樹的\(w_x+de_x\)加第二棵線段樹的\(w_x-de_x+n\)的值

我太傻了,這兩顆線段樹可以分開處理的,我放在一起處理了,空間**,bzoj就過不去了qwq

#include#define ll long long

#define il inline

#define re register

#define db double

#define eps (1e-5)

using namespace std;

const int n=300000+10;

il ll rd()

while(ch>='0'&&ch<='9')

return x*w;

}int to[n<<1],nt[n<<1],hd[n],tot=1;

il void add(int x,int y)

int n,m,w[n],an[n],fa[n],sz[n],de[n],son[n],top[n];

void dfs1(int x)

else

s[o1]=s[o2]+dt;

}} int merge(int o1,int o2)

int quer(int o,int l,int r,int lx)

}s,t;

il void dfs3(int x)

an[x]=s.quer(s.rt[x],1,n+n,w[x]+de[x])+t.quer(t.rt[x],1,n+n,w[x]-de[x]+n);

}int main()

dfs3(1);

for(int i=1;i<=n;i++) printf("%d ",an[i]);

return 0;

}

luogu P1600 天天愛跑步

膜你賽t3考了這題的簡化版,當場自閉。就此把此類題目總結一下。膜你賽題意是這樣的 相當於這個題最後問每個運動員被多少個觀察員觀察到。我們考慮把每條路徑拆成向上和向下兩條,本質相同,我們以向上路徑舉例。發現路徑上滿足 dep s dep x x s 表示路徑起點 的 x 都可以獲得 1 的貢獻。我們差...

luogu P1600 天天愛跑步 LCA

luogu p1600 noip 2016 天天愛跑步 題目描述 小c同學認為跑步非常有趣,於是決定製作一款叫做 天天愛跑步 的遊戲。天天愛跑步 是乙個養成類遊戲,需要玩家每天按時上線,完成打卡任務。這個遊戲的地圖可以看作一一棵包含n個結點和n 1條邊的樹,每條邊連線兩個結點,且任意兩個結點存在一條...

洛谷 P1600 天天愛跑步

題面就不貼上了 把每個玩家的路徑拆成一條到lca的路徑和從lca到終點的路徑 然後,使用樹上差分統計答案即可 那麼,樹上差分是什麼?差分的具體思想是,當某區間內某元素對答案有貢獻,就在區間起點打乙個 1 標記代表多出了乙個對答案有貢獻的元素,在終點打乙個 1標記代表乙個對答案有貢獻的元素在該位置 結...