Advertisement
bibaboba12345

Untitled

Jan 12th, 2023
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.14 KB | None | 0 0
  1. // clang-format off
  2. #define _CRT_SECURE_NO_WARNINGS
  3. #include <iostream>
  4. #include <iomanip>
  5. #include <bitset>
  6. #include <vector>
  7. #include <algorithm>
  8. #include <random>
  9. #include <map>
  10. #include <string>
  11. #include <set>
  12. #include <deque>
  13. #include <string>
  14. #include <cassert>
  15.  
  16. #pragma GCC optimize("Ofast")
  17.  
  18. using namespace std;
  19. const int N = 2e5 + 7, MOD = 1e9 + 7, C = 1000, C2 = 10;
  20. const long long INF = 1e18;
  21. const long double EPS = 1e-9;
  22.  
  23. mt19937 rnd;
  24.  
  25. struct Node {
  26. Node* l, * r, * p;
  27. int sz;
  28. int x, y;
  29. bool IsCycle, push;
  30. Node(int val) {
  31. l = nullptr;
  32. r = nullptr;
  33. p = nullptr;
  34. IsCycle = 0;
  35. push = 0;
  36. sz = 1;
  37. x = val;
  38. y = rnd();
  39. }
  40. };
  41.  
  42. void push(Node* v) {
  43. if (v == nullptr || v->push == 0) {
  44. return;
  45. }
  46. v->push = 0;
  47. swap(v->l, v->r);
  48. if (v->l != nullptr) {
  49. v->l->push ^= 1;
  50. }
  51. if (v->r != nullptr) {
  52. v->r->push ^= 1;
  53. }
  54. }
  55.  
  56. void recalc(Node* v) {
  57. if (v == nullptr) {
  58. return;
  59. }
  60. v->sz = 1;
  61. if (v->l != nullptr) {
  62. v->l->p = v;
  63. v->sz += v->l->sz;
  64. }
  65. if (v->r != nullptr) {
  66. v->r->p = v;
  67. v->sz += v->r->sz;
  68. }
  69. }
  70.  
  71. int sz(Node* v) {
  72. if (v == nullptr) {
  73. return 0;
  74. }
  75. return v->sz;
  76. }
  77.  
  78.  
  79. struct CartesianTree {
  80. Node* nodes[N];
  81. int len;
  82. pair<Node*, Node*> split(Node* v, int k) {
  83. if (v != nullptr) {
  84. v->IsCycle = 0;
  85. }
  86. if (v == nullptr) {
  87. return { nullptr, nullptr };
  88. }
  89. push(v);
  90. if (sz(v->l) >= k) {
  91. if(v->l != nullptr)
  92. v->l->p = nullptr;
  93. auto res = split(v->l, k);
  94. v->l = res.second;
  95. recalc(v);
  96. return { res.first, v };
  97. }
  98. else {
  99. if(v->r != nullptr)
  100. v->r->p = nullptr;
  101. auto res = split(v->r, k - sz(v->l) - 1);
  102. v->r = res.first;
  103. recalc(v);
  104. return { v, res.second };
  105. }
  106. }
  107. Node* merge(Node* l, Node* r) {
  108. if (l != nullptr) {
  109. l->IsCycle = 0;
  110. }
  111. if (r != nullptr) {
  112. r->IsCycle = 0;
  113. }
  114. push(l);
  115. push(r);
  116. if (l == nullptr) return r;
  117. if (r == nullptr) return l;
  118.  
  119. if (l->y > r->y) {
  120. l->r = merge(l->r, r);
  121. recalc(l);
  122. return l;
  123. }
  124. else {
  125. r->l = merge(l, r->l);
  126. recalc(r);
  127. return r;
  128. }
  129. }
  130.  
  131. void rev(Node* v) {
  132. v->push ^= 1;
  133. }
  134.  
  135. void PushUp(Node* v) {
  136. vector<Node*> kek;
  137. kek.clear();
  138. while (v->p != nullptr) {
  139. kek.push_back(v);
  140. v = v->p;
  141. }
  142. kek.push_back(v);
  143. reverse(kek.begin(), kek.end());
  144. for (auto u : kek) {
  145. push(u);
  146. }
  147. }
  148.  
  149. void build(int n) {
  150. for (int i = 1; i <= n; i++) {
  151. auto nn = new Node(i);
  152. nodes[i] = nn;
  153. }
  154. }
  155. int GetInd(Node* v) {
  156. PushUp(v);
  157. int lft = sz(v->l);
  158. while (v->p != nullptr) {
  159. if (v == v->p->r) {
  160. lft++;
  161. lft += sz(v->p->l);
  162. }
  163. v = v->p;
  164. }
  165. return lft;
  166. }
  167. int GetParent(Node* v) {
  168. PushUp(v);
  169. while (v->p != nullptr) {
  170. v = v->p;
  171. }
  172. return v->x;
  173. }
  174.  
  175. /*void unite(int u, int v) {
  176. int p1 = GetParent(nodes[u]);
  177. int p2 = GetParent(nodes[v]);
  178. if (p1 == p2) {
  179. nodes[p1]->IsCycle = 1;
  180. }
  181. else {
  182. if (GetInd(nodes[u]) != 0) {
  183. merge(nodes[p1], nodes[p2]);
  184. }
  185. else {
  186. merge(nodes[p2], nodes[p1]);
  187. }
  188. }
  189. }*/
  190.  
  191. void unite(int u, int v) {
  192. int p1 = GetParent(nodes[u]);
  193. int p2 = GetParent(nodes[v]);
  194. if (p1 == p2) {
  195. nodes[p1]->IsCycle = 1;
  196. }else{
  197. int i1 = GetInd(nodes[u]);
  198. int i2 = GetInd(nodes[v]);
  199. if (i1 == 0 && i2 == 0) {
  200. rev(nodes[p1]);
  201. merge(nodes[p1], nodes[p2]);
  202. return;
  203. }
  204. if (i1 == 0) {
  205. rev(nodes[p1]);
  206. merge(nodes[p1], nodes[p2]);
  207. return;
  208. }
  209. merge(nodes[p1], nodes[p2]);
  210. }
  211. }
  212.  
  213. void break_edge(int u, int v) {
  214. int p = GetParent(nodes[u]);
  215. int ind1 = GetInd(nodes[u]);
  216. int ind2 = GetInd(nodes[v]);
  217. if (!nodes[p]->IsCycle) {
  218. split(nodes[p], max(ind1, ind2));
  219. }
  220. else {
  221. if (max(ind1, ind2) == nodes[p]->sz - 1 && min(ind1, ind2) == 0) {
  222. nodes[p]->IsCycle = 0;
  223. return;
  224. }
  225. auto res = split(nodes[p], max(ind1, ind2));
  226. merge(res.second, res.first);
  227. }
  228. }
  229.  
  230.  
  231. int distance(int u, int v) {
  232. int p1 = GetParent(nodes[u]);
  233. int p2 = GetParent(nodes[v]);
  234. if (p1 != p2) {
  235. return 0;
  236. }
  237. int i1 = GetInd(nodes[v]);
  238. int i2 = GetInd(nodes[u]);
  239. int dist = abs(i1 - i2);
  240. if (nodes[p1]->IsCycle) {
  241. return min(dist, nodes[p1]->sz - dist);
  242. }
  243. return dist;
  244. }
  245. };
  246.  
  247. CartesianTree CT;
  248.  
  249. int n, m, q;
  250.  
  251. signed main() {
  252. #ifdef _DEBUG
  253. freopen("input.txt", "r", stdin);
  254. #else
  255. std::ios::sync_with_stdio(false);
  256. cin.tie(0);
  257. #endif
  258. cin >> n >> m >> q;
  259. CT.build(n);
  260. for (int i = 1; i <= m; i++) {
  261. int u, v;
  262. cin >> u >> v;
  263. CT.unite(u, v);
  264. }
  265. for (int i = 0; i < q; i++) {
  266. char t;
  267. int u, v;
  268. cin >> t >> u >> v;
  269. if (t == '+') {
  270. CT.unite(u, v);
  271. }
  272. if (t == '-') {
  273. CT.break_edge(u, v);
  274. }
  275. if (t == '?') {
  276. cout << CT.distance(u, v) - 1 << "\n";
  277. }
  278. }
  279. }
  280.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement