Description

Mirada生活的城市中有N个小镇,一开始小镇之间没有任何道路连接。随着经济发展,小镇之间陆续建起了一些双向的道路,但是由于经济不太发达,在建设过程中,会保证对于任意两个小镇,最多有一条路径能互相到达。有的时候Miranda会从某个小镇开始进行徒步旅行,每次出发前,她都想选择一个她能到达的最远的小镇作为终点,并且她在行走过程中是不会走回头路的,为了估算这次旅行的时间,她会需要你告诉她这次旅行需要的时间会是多少呢?可以假设通过每条道路都需要单位时间,并且Miranda不会在小镇停留。
 

Input

第一行输入一个整数type,表示数据类型。
第二行两个整数N,Q。
接下来Q行,每行先读入一个整数ty,若ty=1,则接下来读入两个整数u,v,表示小镇u与小镇v建立了一条新道路。若ty=2,读入一个整数u,表示Miranda要开始一次从小镇u出发的旅行。
注意:
若type=1,表示数据进行了加密。记lstans表示最近一次Miranda旅行的时间,那么对于每次操作的u或u,v,都要异或上lstans,即u=u ^ lstans,v=v ^ lstans。
若type=0,则不需要对数据进行处理。

Output

对于每次询问,输出Miranda能到达的最远的小镇的距离是多少。注意Miranda可能只能留在开始的小镇。

 

Sample Input

  1. 0
  2. 5 10
  3. 1 4 5
  4. 2 3
  5. 2 5
  6. 2 1
  7. 1 5 3
  8. 1 1 4
  9. 2 3
  10. 2 5
  11. 1 5 2
  12. 2 1

Sample Output

  1. 0
  2. 1
  3. 0
  4. 3
  5. 2
  6. 3
 

Data Constraint

对于20%的数据,满足:N<=5000,Q<=10000
对于50%的数据,满足:N<=100000,Q<=200000
另外有20%的数据,满足:type=0
对于100%的数据,满足:N<=300000,Q<=500000,type=0或1,解密后的u,v满足1<=u,v<=N,且道路的修建会满足:每一个时刻,都不存在u,v,使得u,v之间能通过多种方式到达

Solution

操作有加边和维护联通块的最远端点,可以用LCT做

抄标程的,根本不会写啊

复杂度为O((N+Q) log N)

  1. #include <stdio.h>
  2. #include <string.h>
  3. #define rg register
  4. #define dmax(a, b) ((a) > (b) ? (a) : (b))
  5.  
  6. inline int rd()
  7. {
  8. rg int x = 0, c = getchar(), f = 1;
  9. for(; c < 48 || c > 57; c = getchar()) if(c == 45) f = -1;
  10. for(; c > 47 && c < 58; c = getchar()) x = (x << 1) + (x << 3) + c - 48;
  11. return x * f;
  12. }
  13.  
  14. inline void dswap(rg int &x, rg int &y)
  15. {
  16. x ^= y ^= x ^= y;
  17. }
  18.  
  19. const int N = 500010;
  20.  
  21. int on_line, n, Q, bel[N], dia[N][2];
  22.  
  23. struct node
  24. {
  25. bool rev;
  26. int sz, ch[2], fa;
  27. }T[N];
  28.  
  29. int find(rg int x) {return bel[x] == x ? x : bel[x] = find(bel[x]);}
  30.  
  31. inline void update(rg int u) {if(u) T[u].sz = T[T[u].ch[0]].sz + T[T[u].ch[1]].sz + 1;}
  32.  
  33. inline bool is_root(rg int u) {rg int fa = T[u].fa; return !fa || !(T[fa].ch[0] == u || T[fa].ch[1] == u);}
  34.  
  35. inline void setch(rg int u, rg int v, rg int c)
  36. {
  37. T[u].ch[c] = v;
  38. if(v) T[v].fa = u;
  39. }
  40.  
  41. inline void mark(rg int u)
  42. {
  43. if(!u)return;
  44. T[u].rev ^= 1;
  45. dswap(T[u].ch[0], T[u].ch[1]);
  46. }
  47.  
  48. inline void down(rg int u)
  49. {
  50. if(!T[u].rev)return;
  51. mark(T[u].ch[0]);
  52. mark(T[u].ch[1]);
  53. T[u].rev = 0;
  54. }
  55.  
  56. inline void rotate(rg int u)
  57. {
  58. int fa = T[u].fa, ft = T[fa].fa, c = T[fa].ch[1] == u;
  59. T[u].fa = ft;
  60. if(!is_root(fa)) setch(ft, u, T[ft].ch[1] == fa);
  61. setch(fa, T[u].ch[!c], c);
  62. setch(u, fa, !c);
  63. update(fa);
  64. }
  65.  
  66. inline void splay(rg int u)
  67. {
  68. static int stack[N];
  69. rg int top = 0, p = u;
  70. for(; !is_root(p); p = T[p].fa) stack[++top] = p;
  71. stack[++top] = p;
  72. for(; top; top--) down(stack[top]);
  73. for(; !is_root(u); rotate(u))
  74. {
  75. rg int fa = T[u].fa, ft = T[fa].fa;
  76. if(is_root(fa)) continue;
  77. ((T[ft].ch[1] == fa) ^ (T[fa].ch[1] == u)) ? rotate(u) : rotate(fa);
  78. }
  79. update(u);
  80. }
  81.  
  82. inline int access(rg int u)
  83. {
  84. int nxt = 0;
  85. for(; u; nxt = u, u = T[u].fa) splay(u), T[u].ch[1] = nxt, update(u);
  86. return nxt;
  87. }
  88.  
  89. inline void make_root(rg int u) {mark(access(u));}
  90.  
  91. inline void link(rg int u, rg int v)
  92. {
  93. make_root(v);
  94. splay(v);
  95. T[v].fa = u;
  96. access(v);
  97. }
  98.  
  99. inline int get_dis(rg int u, rg int v)
  100. {
  101. make_root(u);
  102. access(v);
  103. splay(v);
  104. return T[v].sz - 1;
  105. }
  106.  
  107. inline void merge(rg int a, rg int b)
  108. {
  109. rg int u = find(a), v = find(b);
  110. bel[v] = u;
  111. link(a, b);
  112. rg int lu = dia[u][0], lv = dia[u][1], h = get_dis(dia[u][0], dia[u][1]);
  113. rg int h1 = get_dis(dia[v][0], dia[v][1]);
  114. if(h1 > h) lu = dia[v][0], lv = dia[v][1], h = h1;
  115. for(rg int i = 0; i < 2; i++)
  116. for(rg int j = 0; j < 2; j++)
  117. {
  118. h1 = get_dis(dia[u][i], dia[v][j]);
  119. if(h1 > h) lu = dia[u][i], lv = dia[v][j], h = h1;
  120. }
  121. dia[u][0] = lu, dia[u][1] = lv;
  122. }
  123.  
  124. int main()
  125. {
  126. freopen("hike.in", "r", stdin), freopen("hike.out", "w", stdout);
  127. on_line = rd(), n = rd(), Q = rd();
  128. for(rg int i = 1; i <= n; i++) bel[i] = dia[i][0] = dia[i][1] = i;
  129. rg int last_ans = 0;
  130. while(Q--)
  131. {
  132. rg int ty = rd();
  133. if(ty & 1)
  134. {
  135. rg int u = rd(), v = rd();
  136. if(on_line) u ^= last_ans, v ^= last_ans;
  137. merge(u, v);
  138. }
  139. else{
  140. rg int u = rd();
  141. if(on_line) u ^= last_ans;
  142. rg int p = find(u);
  143. printf("%d\n", last_ans = dmax(get_dis(u, dia[p][0]), get_dis(u, dia[p][1])));
  144. }
  145. }
  146. fclose(stdin), fclose(stdout);
  147. return 0;
  148. }

  

NOI模拟赛(3.13)Hike (远行)的更多相关文章

  1. 小奇模拟赛9.13 by hzwer

    2015年9月13日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿(explo) [题目背景] 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值w)的飞船,按既定路线依次飞 ...

  2. NOI模拟赛 Day1

    [考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...

  3. 6.28 NOI模拟赛 好题 状压dp 随机化

    算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...

  4. NOI 模拟赛 #2

    得分非常惨惨,半个小时写的纯暴力 70 分竟然拿了 rank 1... 如果 OYJason 和 wxjor 在可能会被爆踩吧 嘤 T1 欧拉子图 给一个无向图,如果一个边集的导出子图是一个欧拉回路, ...

  5. 【2018.12.10】NOI模拟赛3

    题目 WZJ题解 大概就是全场就我写不过 $FFT$ 系列吧……自闭 T1 奶一口,下次再写不出这种 $NTT$ 裸题题目我就艹了自己 -_-||| 而且这跟我口胡的自创模拟题 $set1$ 的 $T ...

  6. NOI模拟赛Day5

    T1 有and,xor,or三种操作,每个人手中一个数,求和左边进行某一种运算的最大值,当t==2时,还需要求最大值的个数. test1 20% n<=1000 O(n^2)暴力 test2 2 ...

  7. NOI模拟赛Day4

    看到成绩的时候我的内心** woc第一题写错了呵呵呵呵呵呵呵呵 人不能太浪,会遭报应的** ------------------------------------------------------ ...

  8. NOI模拟赛Day3

    终于A题啦鼓掌~开心~ 开考看完题后,觉得第二题很好捏(傻叉上线 搞到十一点准备弃疗了然后突然发现我会做第一题 于是瞎码了码,就去准备饭票了... 好了,停止扯淡(就我一个我妹子每天不说话好难受QAQ ...

  9. NOI模拟赛Day2

    深深的感受到了自己的水 ---------------------------------------------------------------------------------------- ...

随机推荐

  1. document.body 与 document.documentElement区别介绍

    什么是document.body? 返回html dom中的body节点 即<body> 什么是 document.documentElement? 返回html dom中的root 节点 ...

  2. 2017百度之星资格赛 1003:度度熊与邪恶大魔王(DP)

    .navbar-nav > li.active > a { background-image: none; background-color: #058; } .navbar-invers ...

  3. DataGridView 绑定List<>数据的更新

    使用BindingSource做为中间数据源,使用 bindingSource1.DataSource = productOrderList;dataGridView1.DataSource = bi ...

  4. Ionic之页面传值

    很多时候,我们都进入一个页面往往都是需要将上一级的数据转入到下一级页面中使用,在传传统的html中时经过url来传值,所以ionic也是沿用了html中的方法. 但是还是有点区别于html.我们直接在 ...

  5. AJPFX关于Java内部类及其实例化

    public class Outer {    private int size;    public class Inner {        private int counter = 10;  ...

  6. [ Luogu 3709 ] 大爷的字符串题

    \(\\\) Description 原题题面太过混乱出题人语文凉凉 给出一个长为 \(n\) 的数列 \(A\) ,多次询问: 对于一个区间 \([L_i,R_i]\),把区间内的所有数最少划分成多 ...

  7. hihocoder1067 最近公共祖先·二

    思路: 使用tarjan算法,这是一种离线算法. 实现: #include <bits/stdc++.h> using namespace std; typedef pair<int ...

  8. 正则表达式中的?=,?!,?<=,?<!(预查)解释小栗子

    之前在学正则表达式的时候学的并不是很透彻 感觉看看元字符(元字符要用 \ 转义),限定符(^开头 $结尾),   前面写个范围[a-z],在后面写个{n,}能匹配就行了 当时的自己 然而昨天我参加了个 ...

  9. Azure ARMTemplate模板,VM扩展命令

    Azure ARM模板中,给虚拟机安装扩展脚本的命令 "resources": [ { "apiVersion": "[variables('apiV ...

  10. android开发工具eclipse的安装与配置

    l开发主要应用Eclipse 3.7版本. l辅助工具为jdk.Androidsdk Android环境搭建   –1.1.JDK安装 –1.2.Eclipse安装 –1.3.Android SDK安 ...