BZOJ 3631 [JLOI2014]松鼠的新家 | 树上差分
2017-12-28 19:50
417 查看
链接
题解
看起来是树剖?实际上树上差分就可以解决……
当要给一条路径(u, v) +1的时候,给d[u] += 1, d[v] += 1, d[lca(u, v)] -= 1, d[fa[lca(u, v)]] -= 1。
注意这道题中路径的终点是不 +1的。
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <queue> using namespace std; typedef long long ll; #define enter putchar('\n') #define space putchar(' ') template <class T> void read(T &x){ char c; bool op = 0; while(c = getchar(), c > '9' || c < '0') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x){ if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } const int N = 300005; int n, a , ans , dep , stk , top, pos , seq[2 * N][20], tot, lg[2 * N], fa ; int ecnt, adj , nxt[2 * N], go[2 * N]; void add(int u, int v){ go[++ecnt] = v; nxt[ecnt] = adj[u]; adj[u] = ecnt; } void dfs(int u){ seq[++tot][0] = u, pos[u] = tot, stk[++top] = u; for(int e = adj[u], v; e; e = nxt[e]) if(v = go[e], v != fa[u]){ fa[v] = u, dep[v] = dep[u] + 1; dfs(v); seq[++tot][0] = u; } } int Min(int u, int v){ return dep[u] < dep[v] ? u : v; } void init(){ for(int i = 1, j = 0; i <= tot; i++) lg[i] = i == (1 << (j + 1)) ? ++j : j; for(int j = 1; (1 << j) <= tot; j++) for(int i = 1; i + (1 << j) - 1 <= tot; i++) seq[i][j] = Min(seq[i][j - 1], seq[i + (1 << (j - 1))][j - 1]); } int lca(int u, int v){ int l = pos[u], r = pos[v]; if(l > r) swap(l, r); int j = lg[r - l + 1]; return Min(seq[l][j], seq[r - (1 << j) + 1][j]); } void path_modify(int u, int v, int x){ int anc = lca(u, v); ans[u] += x, ans[v] += x, ans[anc] -= x, ans[fa[anc]] -= x; } int main(){ read(n); for(int i = 1; i <= n; i++) read(a[i]); for(int i = 1, u, v; i < n; i++) read(u), read(v), add(u, v), add(v, u); dfs(1); init(); for(int i = 1; i < n; i++) path_modify(a[i], a[i + 1], 1), path_modify(a[i + 1], a[i + 1], -1); for(int i = top; i; i--) ans[fa[stk[i]]] += ans[stk[i]]; for(int i = 1; i <= n; i++) write(ans[i]), enter; return 0; }
相关文章推荐
- bzoj3631: [JLOI2014]松鼠的新家 (树上差分)
- BZOJ 3631: [JLOI2014]松鼠的新家 树上差分
- 【BZOJ】3631 [JLOI2014]松鼠的新家 LCA+树上差分
- BZOJ3631 [JLOI2014]松鼠的新家 【树上差分】
- BZOJ3631 [JLOI2014]松鼠的新家 【树上差分】
- [JLOI2014][BZOJ3631] 松鼠的新家|树上倍增LCA|差分
- bzoj 3631: [JLOI2014]松鼠的新家(LCA+树上差分)
- [BZOJ3631]JLOI2014松鼠的新家|树上差分
- [bzoj3631][JLOI2014]松鼠的新家 树上差分
- BZOJ 3631: [JLOI2014]松鼠的新家【差分】【LCA】
- [Bzoj3631][JLOI2014]松鼠的新家 (树上前缀和)
- 【树链剖分】【树状数组】【最近公共祖先】【块状树】bzoj3631 [JLOI2014]松鼠的新家
- Bzoj 3631: [JLOI2014]松鼠的新家(树链剖分+线段树)
- BZOJ 3631 JLOI 2014 松鼠的新家 LCA 树链剖分
- BZOJ3631 [JLOI2014] 松鼠的新家
- 【BZOJ3631】[JLOI2014]松鼠的新家
- BZOJ 3631 JLOI2014 松鼠的新家 树链剖分/LCA
- [luoguP3258] [JLOI2014]松鼠的新家(lca + 树上差分)
- 【树链剖分】【JLOI 2014】【bzoj 3631】松鼠的新家
- bzoj 3631: [JLOI2014]松鼠的新家