很好的一道題目,主要是要想到這個方向。
首先,很容易想到的是,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 個...