树链剖分(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;}


原创粉丝点击