天天愛跑步 樹上差分

2021-10-03 15:40:37 字數 2008 閱讀 2410

很好的一道題目,主要是要想到這個方向。

首先,很容易想到的是,s到t的路徑可以拆分成s~lca和lca~t這兩條,現在,我們假設有乙個點x滿足條件,那麼可以列出怎樣的恒等式呢?

我們可以發現等式的左邊就是乙個恆值,不變值。統計答案可以通過統計等式右邊的值來得到,於是,我們可以在樹上維護左邊的值,查詢的時候只需要查詢該子樹下右邊的值的個數即可。

主要的思維就是在這了,其餘的部分就不是太難處理了,可以利用差分的方式來解決問題。

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define lowbit(x) ( x&(-x) )

#define pi 3.141592653589793

#define e 2.718281828459045

#define inf 0x3f3f3f3f

#define half (l + r)>>1

#define lsn rt<<1

#define rsn rt<<1|1

#define lson lsn, l, mid

#define rson rsn, mid+1, r

#define ql lson, ql, qr

#define qr rson, ql, qr

#define myself rt, l, r

#define mp(a, b) make_pair(a, b)

using namespace std;

typedef unsigned long long ull;

typedef unsigned int uit;

typedef long long ll;

const int maxn = 3e5 + 7;

int n, m, head[maxn], cnt, deep[maxn], root[maxn][20], log2[maxn], w[maxn];

struct eddge

}edge[maxn << 1];

inline void addeddge(int u, int v)

inline void _add(int u, int v)

void pre_dfs(int u, int fa)

}return root[u][0];

}vectordelt[maxn], put_in[maxn], redelt[maxn];

int s1[maxn << 1] = , sum[maxn] = , ans[maxn] = ;

void dfs_1(int u, int fa)

s1[deep[u]] += sum[u];

ans[u] += s1[deep[u] + w[u]] - old;

for(auto x : delt[u])

}unordered_maps2;

void dfs_2(int u, int fa)

for(auto x : put_in[u])

ans[u] += s2[deep[u] - w[u]] - old;

for(auto x : redelt[u])

}inline void init()

log2[i] = k;

}}int main()

deep[0] = 0;

pre_dfs(1, 0);

for(int i=1; i<=n; i++) scanf("%d", &w[i]);

for(int i=1, si, ti, _lca; i<=m; i++)

dfs_1(1, 0);

dfs_2(1, 0);

for(int i=1; i<=n; i++) printf("%d%c", ans[i], i == n ? '\n' : ' ');

return 0;

}

NOIP2016 天天愛跑步(樹上差分)

有一棵n nn個點的樹。有m mm個人,第i ii個人從x ix i xi 開始,以每秒1條邊的速度向y iy i yi 跑。每個點有乙個觀察員在第t it i ti 秒觀察,求每個點的觀察員能觀察到幾個人。首先把一條路拆成向上和向下的兩條,分別考慮。向上的路徑,如果能對x xx產生貢獻,必須滿足 ...

NOIP2016 天天愛跑步(樹上差分)

給定一棵樹,從時刻 0 開始,有若干人從 s i 出發向 t i 移動,每單位時刻移動一條邊 對於樹上每個點 x,求 w x 時刻有多少人恰好路過 x n,m 300000 從上午11點做到下午3點45終於做出來了。一開始堅持自己的想法,發現錯了之後不知道怎麼改,無奈看了題解。列出恰好路過的條件並化...

NOIp2016 天天愛跑步 樹上差分

題目型別 lca 思維 傳送門 here 題意 給出一棵樹,有 m 個人在這棵樹上跑步。每個人都從自己的起點 s i 跑到終點 t i 跑過一條邊的時間為1秒。現在每個節點都有乙個觀察員,節點 i 上的觀察員會在第 w i 秒進行觀察,如果有 x 個人此時到達節點 i 則這個觀察員能夠觀察到 x 個...