之前一直用的LCT模板,因为其实个人对LCT和Splay不是很熟,所以用起来总觉得略略的坑爹,过了一段时间就忘了,但事实上很多裸的LCT要改的东西是不多的,所以今天写了些注释,以后可能套起模板来会得心应手一点吧- -0

  1. #pragma warning(disable:4996)
  2. #include <iostream>
  3. #include <cstring>
  4. #include <string>
  5. #include <cstdio>
  6. #include <vector>
  7. #include <algorithm>
  8. #include <map>
  9. using namespace std;
  10.  
  11. #define ll long long
  12. #define maxn 200000
  13. #define INF 0x3f3f3f3f
  14. #define INP INF+1
  15. #define MP make_pair
  16.  
  17. void merge(int mxx[2], int nxx[2], int pval, int pnum)
  18. {
  19. if (pval>mxx[0]){
  20. mxx[1] = mxx[0]; nxx[1] = nxx[0];
  21. mxx[0] = pval; nxx[0] = pnum;
  22. }
  23. else if (pval == mxx[0]){
  24. nxx[0] += pnum;
  25. }
  26. else if (pval>mxx[1]){
  27. mxx[1] = pval; nxx[1] = pnum;
  28. }
  29. else if(pval==mxx[1]){
  30. nxx[1] += pnum;
  31. }
  32. }
  33.  
  34. struct Node
  35. {
  36. /* Splay items(need not to be modified)*/
  37. Node *p, *ch[2];
  38. /* end */
  39.  
  40. /* LCT items(need not to be modified)*/
  41. bool isRoot;
  42. Node *fa;
  43. /* end */
  44.  
  45. /* tags to add(rev should always exist)*/
  46. bool rev;
  47. int add, cov;
  48. /* end */
  49.  
  50. /* data need to be maintained*/
  51. int val, size;
  52. int mx[2], num[2];
  53. /* end */
  54.  
  55. /* default value for the sentinel null(all the TAG and DATA should be set correcly)*/
  56. Node(){
  57. /* DATA */
  58. val = 0; size=0;
  59. mx[0] = mx[1] = -INF;
  60. num[0] = num[1] = 0;
  61. /* TAG */
  62. rev = 0;add = 0; cov = INP;
  63. }
  64. /* end */
  65.  
  66. /* Splay function(need not to be modified)*/
  67. void setc(Node *c, int d){
  68. ch[d] = c;
  69. c->p = this;
  70. }
  71. bool d(){
  72. return p->ch[1] == this;
  73. }
  74. /* end */
  75.  
  76. /* update function(maintain for ALL the DATA)*/
  77. void upd(){
  78. size = ch[0]->size + ch[1]->size + 1;
  79. mx[0] = ch[0]->mx[0]; num[0] = ch[0]->num[0];
  80. mx[1] = ch[0]->mx[1]; num[1] = ch[0]->num[1];
  81. merge(mx, num, val, 1);
  82. merge(mx, num, ch[1]->mx[0], ch[1]->num[0]);
  83. merge(mx, num, ch[1]->mx[1], ch[1]->num[1]);
  84. }
  85. /* end */
  86.  
  87. /* tags function(for ALL the TAG,write a function)*/
  88. void revIt(){
  89. rev ^= 1;
  90. swap(ch[0], ch[1]);
  91. }
  92. void addIt(int vx){
  93. add += vx;
  94. val += vx;
  95. if (mx[0] != -INF) mx[0] += vx;
  96. if (mx[1] != -INF) mx[1] += vx;
  97. }
  98. void setIt(int vx){
  99. add = 0;
  100. cov = vx;
  101. val = vx;
  102. mx[0] = vx; num[0] = size;
  103. mx[1] = -INF; num[1] = 0;
  104. }
  105. /* end */
  106.  
  107. void relax();
  108. void setRoot(Node *f);
  109. }Tnull, *null = &Tnull;
  110.  
  111. /* function setRoot(need not to be modified) */
  112. void Node::setRoot(Node *f){
  113. fa = f;
  114. isRoot = true;
  115. p = null;
  116. }
  117.  
  118. /* function relax(need to be rewrite for ALL the TAG) */
  119. void Node::relax(){
  120. if (cov != INP){
  121. for (int i = 0; i<2; ++i){
  122. if (ch[i] != null) ch[i]->setIt(cov);
  123. }
  124. cov = INP;
  125. }
  126. if (add != 0){
  127. for (int i = 0; i < 2; i++){
  128. if (ch[i] != null) ch[i]->addIt(add);
  129. }
  130. add = 0;
  131. }
  132. if (rev){
  133. for (int i = 0; i < 2; i++){
  134. if (ch[i] != null) ch[i]->revIt();
  135. }
  136. rev = 0;
  137. }
  138. }
  139.  
  140. /* memory part(add C=mem for every iteration)*/
  141. Node mem[maxn], *C = mem;
  142.  
  143. /* function make(need to set the default value for ALL the TAG and DATA)*/
  144. Node *make(int v){
  145. /* DATA */
  146. C->size=1;
  147. C->val = v;
  148. C->mx[0] = v; C->num[0] = 1;
  149. C->mx[1] = -INF; C->num[1] = 0;
  150. /* TAG */
  151. C->rev = 0; C->add = 0;
  152. C->cov = INP;
  153. /* Pointer(need not to be modified) */
  154. C->ch[0] = C->ch[1] = null; C->isRoot = true;
  155. C->p = null;
  156. C->fa = null;
  157. return C++;
  158. }
  159.  
  160. /* function rot(need not to be modified) */
  161. void rot(Node *t){
  162. Node *p = t->p;
  163. p->relax();
  164. t->relax();
  165. bool d = t->d();
  166. p->p->setc(t, p->d());
  167. p->setc(t->ch[!d], d);
  168. t->setc(p, !d);
  169. p->upd();
  170. if (p->isRoot){
  171. p->isRoot = false;
  172. t->isRoot = true;
  173. t->fa = p->fa;
  174. }
  175. }
  176.  
  177. /* function pushTo(need not to be modified) */
  178. void pushTo(Node*t) {
  179. static Node*stk[maxn]; int top = 0;
  180. while (t != null) {
  181. stk[top++] = t;
  182. t = t->p;
  183. }
  184. for (int i = top - 1; i >= 0; --i) stk[i]->relax();
  185. }
  186.  
  187. /* function splay(need not to be modified) */
  188. void splay(Node*u, Node*f = null) {
  189. pushTo(u);
  190. while (u->p != f) {
  191. if (u->p->p == f)
  192. rot(u);
  193. else
  194. u->d() == u->p->d() ? (rot(u->p), rot(u)) : (rot(u), rot(u));
  195. }
  196. u->upd();
  197. }
  198.  
  199. /* Node pointer array*/
  200. Node *v[maxn];
  201. /* The graph stored in the E*/
  202. vector<int> E[maxn];
  203. int n, nQ;
  204.  
  205. /* BFS items, using for construct the Tree */
  206. int que[maxn], fa[maxn], qh = 0, qt = 0;
  207. int wht[maxn];
  208.  
  209. /* function BFS(need not to be modified) */
  210. void bfs()
  211. {
  212. qh = qt = 0;
  213. que[qt++] = 1;
  214. fa[1] = -1;
  215. while (qh < qt){
  216. int u = que[qh++];
  217. for (int i = 0; i < E[u].size(); i++){
  218. int e = E[u][i];
  219. if (e != fa[u]){
  220. fa[e] = u;
  221. v[e]->fa = v[u];
  222. que[qt++] = e;
  223. }
  224. }
  225. }
  226. }
  227.  
  228. /* function expose(need not to be modified) */
  229. Node *expose(Node *u)
  230. {
  231. Node *v;
  232. for (v = null; u != null; v = u, u = u->fa){
  233. splay(u);
  234. u->ch[1]->setRoot(u);
  235. u->setc(v, 1);
  236. v->fa = u;
  237. }
  238. return v;
  239. }
  240.  
  241. /* function makeRoot(need not to be modified) */
  242. void makeRoot(Node *u)
  243. {
  244. expose(u);
  245. splay(u);
  246. u->revIt();
  247. }
  248.  
  249. /* function addEdge(need not to be modified) */
  250. void addEdge(Node *u, Node *v)
  251. {
  252. makeRoot(v);
  253. v->fa = u;
  254. }
  255.  
  256. /* function delEdge(need not to be modified) */
  257. void delEdge(Node *u, Node *v)
  258. {
  259. makeRoot(u);
  260. expose(v); splay(u); u->setc(null, 1); u->upd();
  261. v->setRoot(null);
  262. }
  263.  
  264. /* function find root(need not to be modified) */
  265. Node *find_root(Node *u)
  266. {
  267. expose(u); splay(u);
  268. while (u->ch[0] != null){
  269. u = u->ch[0];
  270. }
  271. splay(u); return u;
  272. }
  273.  
  274. /* function used for query*/
  275. /***************************
  276. prototype:
  277. void xPath(Node *u,Node *v,(int ax))
  278. {
  279. makeRoot(u);
  280. expose(v);
  281. splay(v);
  282. v->xIt((ax))
  283. }
  284. ***************************/
  285. void addPath(Node *u, Node *v, int ax)
  286. {
  287. makeRoot(u);
  288. expose(v);
  289. splay(v);
  290. v->addIt(ax);
  291. }
  292.  
  293. void setPath(Node *u, Node *v, int ax)
  294. {
  295. makeRoot(u);
  296. expose(v);
  297. splay(v);
  298. v->setIt(ax);
  299. }
  300.  
  301. pair<int, int> queryPath(Node *u, Node *v){
  302. makeRoot(u);
  303. expose(v);
  304. splay(v);
  305. return MP(v->mx[1], v->num[1]);
  306. }
  307.  
  308. int main()
  309. {
  310. int T; cin >> T;int ca=0;
  311. while (T--)
  312. {
  313. /* Things to do */
  314. /*************************
  315. C=mem;
  316. initialize E;
  317. read in the wht for nodes;
  318. make for each node;
  319. bfs();
  320. solve for query();
  321. **************************/
  322. C = mem;
  323. scanf("%d%d", &n, &nQ);
  324. for (int i = 1; i <= n; i++){
  325. scanf("%d", wht + i);
  326. v[i] = make(wht[i]);
  327. }
  328. for (int i = 0; i <= n; i++) E[i].clear();
  329. int ui, vi;
  330. for (int i = 0; i < n - 1; i++){
  331. scanf("%d%d", &ui, &vi);
  332. E[ui].push_back(vi); E[vi].push_back(ui);
  333. }
  334. bfs();
  335. int cmd, xi, yi, ai, bi;
  336. Node *nx, *ny, *na, *nb;
  337. printf("Case #%d:\n",++ca);
  338. while (nQ--){
  339. scanf("%d", &cmd);
  340. if (cmd == 1) scanf("%d%d%d%d", &xi, &yi, &ai, &bi);
  341. else if (cmd == 2 || cmd == 3) scanf("%d%d%d", &ai, &bi, &xi);
  342. else scanf("%d%d", &ai, &bi);
  343.  
  344. if (cmd == 1){
  345. nx = v[xi]; ny = v[yi];
  346. na = v[ai]; nb = v[bi];
  347. delEdge(nx, ny);
  348. addEdge(na, nb);
  349. }
  350. else if (cmd == 2){
  351. nx = v[ai]; ny = v[bi];
  352. setPath(nx, ny, xi);
  353. }
  354. else if (cmd == 3){
  355. nx = v[ai]; ny = v[bi];
  356. addPath(nx, ny, xi);
  357. }
  358. else{
  359. nx = v[ai]; ny = v[bi];
  360. pair<int, int> ans = queryPath(nx, ny);
  361. if (ans.first <= -INF) printf("ALL SAME\n");
  362. else printf("%d %d\n", ans.first, ans.second);
  363. }
  364. }
  365. }
  366. return 0;
  367. }

LCT模板的更多相关文章

  1. LCT 模板及套路总结

    这一个月貌似已经考了无数次\(LCT\)了..... 保险起见还是来一发总结吧..... A. LCT 模板 \(LCT\) 是由大名鼎鼎的 \(Tarjan\) 老爷发明的. 主要是用来维护树上路径 ...

  2. [洛谷P1501] [国家集训队]Tree II(LCT模板)

    传送门 这是一道LCT的板子题,说白了就是在LCT上支持线段树2的操作. 所以我只是来存一个板子,并不会讲什么(再说我也不会,只能误人子弟2333). 不过代码里的注释可以参考一下. Code #in ...

  3. LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板

    P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...

  4. BZOJ2002 & LCT模板(分块不会搞)

    题意: 看题. 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿 着一条直线摆上n个装置,每个装置设定初 ...

  5. bzoj2049-洞穴勘测(动态树lct模板题)

    Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...

  6. Luogu 3690 LCT - 模板

    推荐几篇比较好的博客: FlashHu 的 讲解比较好 : 传送门 Candy 的 代码~ : 传送门 以及神犇Angel_Kitty的 学习笔记: 传送门 Code V 模板 #include< ...

  7. BZOJ 1180 / 2843 LCT模板题_双倍经验

    一大早上到机房想先拍一下模板,热热身. 结果....对照着染色敲的 LCT 竟然死活也调不过去(你说我抄都能抄错) 干脆自己重新敲了一遍,10min就敲完了....... 还是要相信自己 Code: ...

  8. BZOJ3282: Tree (LCT模板)

    Description 给定N个点以及每个点的权值,要你处理接下来的M个操作. 操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和 ...

  9. LCT模板(学习笔记)(洛谷3690)(加边,删边,修改点权)

    最近学习了一波LCT qwq 强势安利Flashhu的博客!!!!! 真的特别详细(可惜我不会弄链接) 如果有想要学习\(LCT\)的同学,可以直接看他的博客 我这里就简单写一点自己的体会啊. \(L ...

随机推荐

  1. angularjs2 学习笔记(二) 组件

    angular2 组件 首先了解angular2 组件的含义 angular2的应用就是一系列组件的集合 我们需要创建可复用的组件供多个组件重复使用 组件是嵌套的,实际应用中组件是相互嵌套使用的 组件 ...

  2. WPF实现渐变淡入淡出的动画效果

    1.实现原理 1.1 利用UIElement.OpacityMask属性,用于改变对象区域的不透明度的画笔.可以使元素的特定区域透明或部分透明,从而实现比较新颖的效果. 1.2 OpacityMask ...

  3. C 基于UDP实现一个简易的聊天室

    引言 本文是围绕Linux udp api 构建一个简易的多人聊天室.重点看思路,帮助我们加深 对udp开发中一些api了解.相对而言udp socket开发相比tcp socket开发注意的细节要少 ...

  4. MIFARE系列6《射频卡与读写器的通讯》

    1. 复位应答(Answer to request) 读写器呼叫磁场内的卡片,卡片对呼叫做出应答.对刚进入磁场得到电复位处于休闲状态的卡片,卡请求(REQA,0x26):对于已进行过读写操作并进入休眠 ...

  5. 在meteor中使用支付,以及与服务器进行数据交互

    how to use Meteor.http.call? Meteor.http is only available on sever side http模块仅能用于server端. 1,add ht ...

  6. TFS(Taobao File System)安装方法

    文章目录: 一.TFS(Taobao File System)安装方法 二.TFS(Taobao File System)配置dataServer.分区.挂载数据盘 三.TFS(Taobao File ...

  7. [小技巧]让C#的空值处理变得更优雅

    参考 http://www.codeproject.com/Articles/739772/Dynamically-Check-Nested-Values-for-IsNull-Values?msg= ...

  8. 22.I/O特性

    IO资源 IO是与外界沟通和控制的通道,fpga提供了丰富的IO和一些实用的特性. 本文简要的将主要的特性摘录下来做设计参考用.具体参数参考handbook. 第一部分:IO特性概述 -----通过软 ...

  9. windows多线程编程(一)(转)

    源出处:http://www.cnblogs.com/TenosDoIt/archive/2013/04/15/3022036.html CreateThread:Windows的API函数(SDK函 ...

  10. 软件工程课后作业——用JAVA编写的随机产生30道四则运算

    package com.java.sizeyunsuan; public class lianxi { String f() { int i=(int)(Math.random()*10); int ...