树链剖分(QTREE)
来源:互联网 发布:手机淘宝页面不正常 编辑:程序博客网 时间:2024/05/21 17:37
只敢说写过了这个题,下次能不能写过就靠运气了。
发现不是很难调,代码量也还好,只写了140+行,3665B,但速度奇慢,也许是常数太大。。
照例代码,各位神犇可以直接忽视我的缩行:
#include <stdio.h>#include <memory.h>#define maxn 10010#define tail_zero(i) lgr[i]#define oo 0x3F3F3F3F#define base 16384#define clr(a) memset (a, 0, sizeof (a))typedef int arr[maxn];int etop, htop, n;arr da_data[17];arr bfr, bto, pred, succ, hash, depth, lgr, cost, size, queue, edge, child;int next[maxn << 1], point[maxn << 1];int st[base << 1], *pnt = da_data[0], *da[17];inline int max (int i, int j){ return i > j ? i : j;}inline void adde (int s, int t, int w){ point[++etop] = t; next[etop] = edge[s]; edge[s] = etop; cost[etop >> 1] = w;}inline void st_modify (int i, int v){ for (st[i += base] = v, i >>= 1; i; i >>= 1) st[i] = max (st[i << 1], st[i << 1 | 1]);}inline int st_query (int l, int r){ if (l > r) return -oo; int ans = -oo; for (l += base - 1, r += base + 1; l ^ r ^ 1; l >>= 1, r >>= 1) { if (~l & 1) ans = max (st[l ^ 1], ans); if ( r & 1) ans = max (ans, st[r ^ 1]); } return ans;}inline int lca (int s, int t){ int k; if (depth[s] > depth[t]) k = s, s = t, t = k; for (; depth[s] != depth[t]; ) t = da[tail_zero (depth[t] - depth[s])][t]; if (s == t) return s; for (k = lgr[depth[s]] + 1; k >= 0; --k) if (da[k][s] != da[k][t]) s = da[k][s], t = da[k][t]; return pnt[s];}inline int query (int h, int l){ int ans = -oo, t; while (bfr[h] != bfr[l]) { ans = max (ans, st_query (hash[succ[bfr[l]]], hash[pred[l]])); ans = max (ans, cost[pred[bfr[l]]]); if ((t = point[pred[bfr[l]] << 1]) != bfr[l]) l = t; else l = point[pred[bfr[l]] << 1 | 1]; } if (pred[l]) ans = max (ans, st_query (hash[succ[h]], hash[pred[l]])); return ans;}inline void init (){ int i, e, head = 0, tail = 1, p; queue[1] = depth[1] = 1, htop = 0; for (; head != tail; ) for (e = edge[i = queue[++head]]; e; e = next[e]) if (!depth[p = point[e]]) queue[++tail] = p, depth[p] = depth[i] + 1, pnt[p] = i, pred[p] = e >> 1; for (i = n; i; --i) { ++size[p = queue[i]]; if (size[child[pnt[p]]] < size[p]) child[pnt[p]] = p, succ[pnt[p]] = pred[p]; size[pnt[p]] += size[p]; } for (i = 1; i <= n; ++i) { for (e = 1, p = queue[i]; (1 << e) <= depth[p]; ++e) da[e][p] = da[e - 1][da[e - 1][p]]; if (!hash[pred[p]]) for (e = child[p]; e; e = child[e]) hash[pred[e]] = ++htop, st_modify (htop, cost[pred[e]]); if (child[p]) bfr[child[p]] = bfr[p], bto[bfr[p]] = child[p]; }}inline void solve(){ clr (da_data), clr (bfr), clr (bto), clr (size), clr (hash), clr (depth), clr (edge), clr (succ), clr (pred), clr (child), clr (st); int i, a, b, c; char cmd[50]; scanf ("%d", &n); for (etop = i = 1; i < n; ++i) scanf ("%d%d%d", &a, &b, &c), adde (a, b, c), adde (b, a, c); for (i = 1; i <= n; ++i) bfr[i] = bto[i] = i; init (); for (scanf ("%s", cmd); cmd[0] != 'D'; scanf ("%s", cmd)) { scanf ("%d%d", &a, &b); if (cmd[0] == 'Q') i = lca (a, b), printf ("%d\n", max (query (i, a), query (i, b))); else if (hash[a]) st_modify (hash[a], b); else cost[a] = b; }}int main (){ freopen ("qtree.in" , "r", stdin); freopen ("qtree.out", "w", stdout); int t; for (t = 2; t <= maxn; ++t) lgr[t] = lgr[t - 1] + ((t & -t) == t); for (t = 0; t <= 16; ++t) da[t] = da_data[t]; scanf ("%d", &t); for (; t; --t) solve (); return 0;}
- 树链剖分(QTREE)
- Spoj 375 QTREE(树链剖分)
- SPOJ QTREE(树链剖分模板)
- Qtree树链剖分
- 树链剖分(SPOJ-QTREE)(模板)
- 【树链剖分】QtreeⅣ&QtreeⅤ题解
- SPOJ375 QTREE 树链剖分入门
- SPOJ - QTREE (树链剖分)
- 【SPOJ QTREE】树链剖分模板
- SPOJ QTREE(树链剖分)
- SPOJ QTREE Query on a tree(树链剖分)
- SPOJ 375 QTREE系列-Query on a tree (树链剖分)
- SPOJ QTREE Query on a tree (树链剖分)
- SPOJ QTREE - Query on a tree(树链剖分)
- SPOJ 题目 375 QTREE - Query on a tree(树链剖分)
- [SPOJ QTREE] Query on a tree (树链剖分)
- SPOJ QTREE Query on a tree(树链剖分+线段树)
- 树链剖分学习笔记 && SPOJ QTREE
- 2D—Graphics初步研究(更改排版)
- java代码
- [iOS开发必备工具之]图片的异步加载与图片缓存(1)
- hdu 1394
- [ActiveRecord] 之四:Cascade
- 树链剖分(QTREE)
- VC6.0中C4541号警告的原因以及解决方案
- 系统架构之二(棋牌类游戏常用架构)
- android滑动基础篇
- [ActiveRecord] 之五:ActiveRecordMediator
- ExpandableListView基本实现—能运行
- 读取RSS源的天气预报Web Server实现
- (2011.07.04-2011.07.09)六天的学习小记
- [ActiveRecord] 之六:继承