BZOJ3307 雨天的尾巴
2015-05-16 11:57
351 查看
首先考虑序列怎么做。。。
只要把操作差分了,记录在每个点上
然后维护一棵权值线段树,表示每个颜色出现的次数,支持单点修改和查询最大值操作
只要把序列扫一遍就好了,时间复杂度$O(n + m*logZ)$,其中$n$表述序列长度,$m$表示操作次数,$Z$表示颜色集合大小
于是树形的时候,先树链剖分,然后把操作离线,对每一条链都扫一遍就好了,时间复杂度$O(n + m*logn*logZ)$
View Code
(p.s. 窝比较懒,所以没有把颜色离散化,直接搞了动态开点线段树)
只要把操作差分了,记录在每个点上
然后维护一棵权值线段树,表示每个颜色出现的次数,支持单点修改和查询最大值操作
只要把序列扫一遍就好了,时间复杂度$O(n + m*logZ)$,其中$n$表述序列长度,$m$表示操作次数,$Z$表示颜色集合大小
于是树形的时候,先树链剖分,然后把操作离线,对每一条链都扫一遍就好了,时间复杂度$O(n + m*logn*logZ)$
/************************************************************** Problem: 3307 User: rausen Language: C++ Result: Accepted Time:5120 ms Memory:86068 kb ****************************************************************/ #include <cstdio> #include <algorithm> using namespace std; const int N = 1e5 + 5; const int Z = 1e9 + 5; inline int read(); struct seg { seg *ls, *rs; int mx, wmx; int tag; seg() {} #define Len (1 << 16) inline void* operator new(size_t) { static seg *mempool, *c; if (mempool == c) mempool = (c = new seg[Len]) + Len; return c++; } #undef Len inline void operator = (const seg &s) { mx = s.mx, wmx = s.wmx; } inline void update() { if (!ls && !rs) this -> mx = 0; else if (!ls || !rs) *this = (ls ? *ls : *rs); else if (ls -> mx >= rs -> mx) *this = *ls; else *this = *rs; } inline void clear() { tag = 1, mx = 0; } inline void push() { if (tag) { if (ls) ls -> clear(); if (rs) rs -> clear(); tag = 0; } } #define mid (l + r >> 1) void modify(int l, int r, int pos, int d) { if (l == r) { mx += d, wmx = l; return; } push(); if (pos <= mid) { if (!ls) ls = new()seg; ls -> modify(l, mid, pos, d); } else { if (!rs) rs = new()seg; rs -> modify(mid + 1, r, pos, d); } update(); } #undef mid } *T; struct edge { int next, to; edge(int _n = 0, int _t = 0) : next(_n), to(_t) {} } e[N << 1]; int first , tot; struct oper { int next, z, d; oper(int _n = 0, int _z = 0, int _d = 0) : next(_n), z(_z), d(_d) {} } op[N << 6]; int First , tot_op; struct tree_node { int fa, son, top; int sz, dep; } tr ; int n, m; int ans ; inline void Add_Edges(int x, int y) { e[++tot] = edge(first[x], y), first[x] = tot; e[++tot] = edge(first[y], x), first[y] = tot; } #define y e[x].to void dfs(int p) { int x; tr[p].sz = 1; for (x = first[p]; x; x = e[x].next) if (y != tr[p].fa) { tr[y].fa = p, tr[y].dep = tr[p].dep + 1; dfs(y); tr[p].sz += tr[y].sz; if (tr[tr[p].son].sz < tr[y].sz) tr[p].son = y; } } void DFS(int p) { int x; if (!tr[p].son) return; tr[tr[p].son].top = tr[p].top, DFS(tr[p].son); for (x = first[p]; x; x = e[x].next) if (y != tr[p].fa && y != tr[p].son) tr[y].top = y, DFS(y); } #undef y inline void Add_oper(int x, int y, int z) { y = tr[y].son; op[++tot_op] = oper(First[x], z, 1), First[x] = tot_op; op[++tot_op] = oper(First[y], z, -1), First[y] = tot_op; } inline void work(int x, int y, int z) { while (tr[x].top != tr[y].top) { if (tr[tr[x].top].dep < tr[tr[y].top].dep) swap(x, y); Add_oper(tr[x].top, x, z); x = tr[tr[x].top].fa; } if (tr[x].dep < tr[y].dep) swap(x, y); Add_oper(y, x, z); } void get_ans(int p) { int x; for (x = First[p]; x; x = op[x].next) T -> modify(1, Z, op[x].z, op[x].d); ans[p] = T -> mx == 0 ? 0 : T -> wmx; if (tr[p].son) get_ans(tr[p].son); } int main() { int i, x, y, z; n = read(), m = read(); for (i = 1; i < n; ++i) Add_Edges(read(), read()); dfs(1); tr[1].top = 1, DFS(1); for (i = 1; i <= m; ++i) { x = read(), y = read(), z = read(); work(x, y, z); } T = new()seg; for (i = 1; i <= n; ++i) if (tr[i].top == i) { T -> clear(); get_ans(i); } for (i = 1; i <= n; ++i) printf("%d\n", ans[i]); return 0; } inline int read() { static int x; static char ch; x = 0, ch = getchar(); while (ch < '0' || '9' < ch) ch = getchar(); while ('0' <= ch && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x; }
View Code
(p.s. 窝比较懒,所以没有把颜色离散化,直接搞了动态开点线段树)
相关文章推荐
- 【BZOJ3307】雨天的尾巴 线段树合并
- 【BZOJ3307】雨天的尾巴(树链剖分+树上差分+线段树)
- BZOJ 3307 雨天的尾巴 线段树
- BZOJ_3307_雨天的尾巴_线段树合并+树上差分
- bzoj 3307: 雨天的尾巴【树剖lca+树上差分+线段树合并】
- BZOJ 3307: 雨天的尾巴
- BZOJ 3307: 雨天的尾巴 线段树合并 树上差分
- BZOJ 3307: 雨天的尾巴( LCA + 线段树合并 )
- bzoj 3307: 雨天的尾巴 (线段树合并+LCA)
- BZOJ3307 雨天的尾巴 (树链剖分 线段树合并 dfs相关)
- [BZOJ3307][线段树合并]雨天的尾巴
- [BZOJ3307][雨天的尾巴][树链剖分+线段树]
- bzoj 3307: 雨天的尾巴 线段树
- [bzoj3307]雨天的尾巴【线段树】
- BZOJ 3307 雨天的尾巴 树上差分+lca+权值线段树合并
- 【BZOJ3307】雨天的尾巴-线段树合并+树上差分
- bzoj3307 雨天的尾巴
- [bzoj3307]雨天的尾巴_线段树合并
- bzoj 3307: 雨天的尾巴 线段树合并
- bzoj 3307 雨天的尾巴