题目链接
对于每一个节点,记录这个节点所在链的信息:
ls:(链的上端点)距离链内部近期的白点距离
rs:(链的下端点)距离链内部近期的白点距离
注意以上都是实边
虚边的信息用一个set维护。
set维护的是对于每一个不是链上,可是this的子树,那些子树中距离this近期的白点距离。

#include <stdio.h>
#include <string.h>
#include <set>
#include <algorithm>
#include <iostream>
#include <vector>
template <class T>
inline bool rd(T &ret) {char c; int sgn;if (c = getchar(), c == EOF) return 0;while (c != '-' && (c<'0' || c>'9')) c = getchar();sgn = (c == '-') ?

-1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } template <class T> inline void pt(T x) { if (x <0) { putchar('-'); x = -x; } if (x>9) pt(x / 10); putchar(x % 10 + '0'); } using namespace std; typedef long long ll; const int inf = 1e9; const int N = 1e5 + 10; struct Node *null; struct Node{ multiset<int>chain; Node *fa, *ch[2]; int size; int col, ls, rs, id, len, edge; //黑色col=-inf, 白色col=0 len是链长 bool rev; inline void put(){ printf("%d son:%d,%d fa:%d len:%d (%d,%d) col:%d\n", id, ch[0]->id, ch[1]->id, fa->id, len, ls, rs, col); for (auto i : chain)printf("%d ", i); puts(""); } inline void clear(int _id){ fa = ch[0] = ch[1] = null; size = 1; rev = 0; len = edge = 0; id = _id; chain.clear(); chain.insert(inf); col = inf; ls = rs = inf; } inline void push_up(){ size = 1 + ch[0]->size + ch[1]->size; len = edge + ch[0]->len + ch[1]->len; int m0 = min(col, *chain.begin()), ml = min(m0, ch[0]->rs + edge), mr = min(m0, ch[1]->ls); ls = min(ch[0]->ls, ch[0]->len + edge + mr); rs = min(ch[1]->rs, ch[1]->len + ml); } inline void push_down(){ if (rev){ ch[0]->flip(); ch[1]->flip(); rev = 0; } } inline void setc(Node *p, int d){ ch[d] = p; p->fa = this; } inline bool d(){ return fa->ch[1] == this; } inline bool isroot(){ return fa == null || fa->ch[0] != this && fa->ch[1] != this; } inline void flip(){ if (this == null)return; swap(ch[0], ch[1]); rev ^= 1; } inline void go(){//从链头開始更新到this if (!isroot())fa->go(); push_down(); } inline void rot(){ Node *f = fa, *ff = fa->fa; int c = d(), cc = fa->d(); f->setc(ch[!c], c); this->setc(f, !c); if (ff->ch[cc] == f)ff->setc(this, cc); else this->fa = ff; f->push_up(); } inline Node*splay(){ go(); while (!isroot()){ if (!fa->isroot()) d() == fa->d() ? fa->rot() : rot(); rot(); } push_up(); return this; } void debug(Node *x){ if (x == null)return; x->put(); debug(x->ch[0]); debug(x->ch[1]); } inline Node* access(){//access后this就是到根的一条splay,而且this已经是这个splay的根了 for (Node *p = this, *q = null; p != null; q = p, p = p->fa){ p->splay(); // debug(q); puts(""); debug(p); puts(""); if (p->ch[1] != null) p->chain.insert(p->ch[1]->ls); if (q != null) p->chain.erase(p->chain.find( q->ls )); p->setc(q, 1); p->push_up(); // debug(q); puts(""); debug(p); puts(""); } return splay(); } inline Node* find_root(){ Node *x; for (x = access(); x->push_down(), x->ch[0] != null; x = x->ch[0]); return x; } void make_root(){ access()->flip(); } void cut(){//把这个点的子树脱离出去 access(); ch[0]->fa = null; ch[0] = null; push_up(); } void cut(Node *x){ if (this == x || find_root() != x->find_root())return; else { x->make_root(); cut(); } } void link(Node *x){ if (find_root() == x->find_root())return; else { make_root(); fa = x; } } }; Node pool[N], *tail; Node *node[N]; vector<int>G[N]; void dfs(int u, int fa){ for (int v : G[u]){ if (v == fa)continue; node[v]->fa = node[u]; node[v]->edge = 1; dfs(v, u); node[u]->chain.insert(node[v]->ls); } node[u]->push_up(); } int n, q; void debug(Node *x){ if (x == null)return; x->put(); debug(x->ch[0]); debug(x->ch[1]); } int main(){ while (cin >> n){ tail = pool; null = tail++; null->clear(0); null->size = 0; for (int i = 1; i <= n; i++) { G[i].clear(); node[i] = tail++; node[i]->clear(i); } for (int i = 1, u, v; i < n; i++){ rd(u); rd(v); G[u].push_back(v); G[v].push_back(u); } dfs(1, 1); // for (int i = 1; i <= n; i++)debug(node[i]), puts(""); rd(q); while (q--){ int u, v; rd(u); rd(v); if (u == 0) { node[v]->access(); if (node[v]->col == inf)node[v]->col = 0; else node[v]->col = inf; node[v]->push_up(); } else { node[v]->access(); int ans = min(*node[v]->chain.begin(), node[v]->rs); if (ans == inf)ans = -1; pt(ans); puts(""); } // for (int i = 1; i <= n; i++)debug(node[i]), puts(""); } } return 0; }

转载于:https://www.cnblogs.com/lxjshuju/p/7388973.html

SPOJ QTREE5 lct相关推荐

  1. SPOJ - QTREE5 Query on a tree V 边分治

    题目传送门 题意:给你一棵树, 然后树上的点都有颜色,且原来为黑,现在有2个操作,1 改变某个点的颜色, 2 询问树上的白点到u点的最短距离是多少. 题解: 这里用的还是边分治的方法. 把所有东西都抠 ...

  2. SPOJ QTREE6 lct

    题目链接 岛娘出的题.还是比較easy的 #include <iostream> #include <fstream> #include <string> #inc ...

  3. SPOJ OTOCI 动态树 LCT

    SPOJ OTOCI 裸的动态树问题. 回顾一下我们对树的认识. 最初,它是一个连通的无向的无环的图,然后我们发现由一个根出发进行BFS 会出现层次分明的树状图形. 然后根据树的递归和层次性质,我们得 ...

  4. 洛谷 - P6292 区间本质不同子串个数(SAM+LCT+线段树)

    题目链接:点击查看 题目大意:给出一个长度为 n 的字符串,再给出 m 次询问,每次询问需要回答区间 [ l , r ] 内有多少个本质不同的字符串 题目分析:首先简化模型,回顾一下如何求解 &quo ...

  5. SPOJ QTREE

    QTREE /*题目大意:维护一棵树,允许修改边权以及查询链上最大值题解:我们将边权转为点权,标记在深度较深的点上,树链剖分后用线段树处理即可 */ #include <cstdio> # ...

  6. 【Qtree】Query on a tree系列LCT解法

    Qtree1-7 Qtree1 裸的树链剖分,当然也可以用LCT写,就不说什么了... Qtree2 倍增lca,当然也可以用LCT写,就不说什么了... Qtree3 裸的树链剖分,当然也可以用LC ...

  7. QTREE系列1,4,5,6,7 LCT

    QTREE1 题意: 给出一棵N(N <= 10000)个点的树,要求支持: 1.改变第i条边的权值 2.求a->b上的最大边权 解: 直接树剖或LCT即可 代码 1.LCT(660ms) ...

  8. Qtree LCT系列

    Qtree1,2,3暂缺 Qtree4思路 总是有机房大佬问我怎么做(抄题解不就好了吗?),那我就讲一讲我紊乱的思路吧. 应该不难想到边权下放到子节点,有了这个基础,我们对细节的处理就不用那么模糊了. ...

  9. LCT (Link-cut-tree)

    文章目录 LCT LCT定义 学习资料 四种操作 解决的问题 LCT 快退役了学一波以前听过很多次但没时间学的东西 LCT定义 学习资料 建议读论文 维基百科 https://en.wikipedia ...

最新文章

  1. React + Typescript + Webpack 开发环境配置
  2. Android 进程间通信 实例分析
  3. leetcode 509. 斐波那契数(dfs)
  4. RAC crs_stat unknown资源状态处理
  5. 【Linux使用】Centos 7 设置机器名/激活网络接口
  6. notepad++正则表达式使用
  7. 170824、storm 环境搭建
  8. Spring 的 IOC原理
  9. VirtualBox的BUG:没超线程也认为有
  10. Maven打包:Error injecting:xxxxxxx / java.lang.NoClassDefFoundError: xxxxxx
  11. 我们管理20人团队的方法
  12. 【数论】Pollard-Rho 算法总结
  13. 二人成团,阿里云服务器拼团活动开启
  14. Redis BitMap结构实现签到、连续签到统计
  15. Java: 线上故障如何快速排查?来看这套技巧大全(高德地图的总结)
  16. js关闭浏览器当前页(iframe)
  17. 步步为营-墙棋AI人机对战(Android)
  18. go源码阅读——type.go
  19. 谷歌又推出Chrome 55浏览器安卓版啦!
  20. 计算机本科毕业论文和毕设注意事项

热门文章

  1. Spring和Junit整合
  2. pc端游戏修改器_原神:不要吐槽手机内存了,想要获得最佳游戏体验,PC端最合适...
  3. 服务器系统js文件报错,js服务器文件
  4. python的仿真效果好吗_Python SimPy 仿真系列 (1)
  5. 如何正确认识C语言在当今编程领域的地位
  6. php拼接多个insert,php – 将多个INSERTS分成一个表和多个表
  7. centos6.5 安装多个mysql_在centos6,5(64位)系统安装多实例mysql5.6
  8. 几何画板200个经典课件_项目制学科联动 | 金芬娥首席工作室:灵动“画板”,研修创新,协同进步...
  9. 【渝粤教育】国家开放大学2018年春季 0089-21TInternet和Intranet应用 参考试题
  10. 【渝粤教育】广东开放大学 系统工程 形成性考核 (25)