Advertisement
Guest User

Untitled

a guest
Apr 18th, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.58 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. mt19937 rr(random_device{}());
  6.  
  7. struct item {
  8. int key, prior, cnt, sum;
  9. bool cycle = 0, rev = 0;
  10. item *l, *r, *parent;
  11.  
  12. item() : l(nullptr), r(nullptr), parent(nullptr), cnt(1) {};
  13.  
  14. item(int key, int prior) : l(nullptr), r(nullptr), key(key), parent(nullptr), cnt(1) {};
  15. };
  16.  
  17. int h = 0;
  18.  
  19. int cnt(item *t) {
  20. if (!t)
  21. return 0;
  22. return t->cnt;
  23. }
  24.  
  25. void push(item *it) {
  26. if (it && it->rev) {
  27. it->rev = false;
  28. swap(it->l, it->r);
  29. if (it->l) it->l->rev ^= true;
  30. if (it->r) it->r->rev ^= true;
  31. }
  32. }
  33.  
  34. void update(item *t) {
  35. if (t) {
  36. t->cnt = cnt(t->l) + cnt(t->r) + 1;
  37. }
  38. }
  39.  
  40. void print(item *t) {
  41. if (t) {
  42. push(t);
  43. print(t->l);
  44. cout << t->key + 1 << " ";
  45. if (t->parent) {
  46. // cout << t->parent->key << " papa " << endl;
  47. }
  48. print(t->r);
  49. }
  50. }
  51.  
  52. //void split(item * t, item * &l, item * &r, int pos, int add)
  53.  
  54. pair<item *, item *> split(item *root, int key, int add) {
  55. if (root == nullptr)
  56. return make_pair(nullptr, nullptr);
  57. push(root);
  58. int cur = add + cnt(root->l);
  59. if (cur < key) {
  60. pair<item *, item *> splitted = split(root->r, key, cur + 1);
  61. root->r = splitted.first;
  62. if (splitted.first)
  63. splitted.first->parent = root;
  64. if (splitted.second)
  65. splitted.second->parent = nullptr;
  66. update(root);
  67. return make_pair(root, splitted.second);
  68. } else {
  69. pair<item *, item *> splitted = split(root->l, key, add);
  70. root->l = splitted.second;
  71. if (splitted.second)
  72. splitted.second->parent = root;
  73. if (splitted.first)
  74. splitted.first->parent = nullptr;
  75. update(root);
  76. return make_pair(splitted.first, root);
  77. }
  78. }
  79.  
  80.  
  81. item *merge(item *l, item *r) {
  82.  
  83. if (!l || !r)
  84. return l ? l : r;
  85. else {
  86. push(l);
  87. push(r);
  88. if (l->prior > r->prior) {
  89. l->r = merge(l->r, r);
  90. l->r->parent = l;
  91. update(l);
  92. return l;
  93. } else {
  94. r->l = merge(l, r->l);
  95. r->l->parent = r;
  96. update(r);
  97. return r;
  98. }
  99. }
  100. }
  101.  
  102. void reverse(item *&t, int l, int r) {
  103. item *t1, t2, t3;
  104. auto v = split(t, l, 0);
  105. auto v1 = split(v.second, r - l + 1, 0);
  106. v1.first->rev ^= true;
  107. t = merge(v.first, v1.first);
  108. t = merge(t, v1.second);
  109. // split (t, t1, t2, l);
  110. // split (t2, t2, t3, r-l+1);
  111. // t2->rev ^= true;
  112. // merge (t, t1, t2);
  113. // merge (t, t, t3);
  114. }
  115.  
  116. item *get_root(item *t) {
  117. int cnt = 0;
  118. while (t && t->parent) {
  119. t = t->parent;
  120. cnt++;
  121. if (cnt == 10000000) {
  122. assert(0);
  123. }
  124. }
  125. return t;
  126. }
  127.  
  128. void super_push(item *t) {
  129. if (t == nullptr) {
  130. return;
  131. }
  132. super_push(t->parent);
  133. push(t);
  134. }
  135.  
  136. int get_number(item *t) {
  137. super_push(t);
  138. int res = cnt(t->l);
  139. int cn = 0;
  140. while (t) {
  141. if (t->parent) {
  142. if (t->parent->r == t) {
  143. res += cnt(t->parent->l) + 1;
  144. }
  145. }
  146. cn++;
  147. if (cn == 10000000) {
  148. assert(0);
  149. }
  150. t = t->parent;
  151. }
  152. return res;
  153. }
  154.  
  155.  
  156. const int MAXN = 1e5 + 69;
  157. item *a[MAXN];
  158.  
  159. inline bool the_biggest(item *t) {
  160. if ((!t->parent && !t->r) || (t->parent && t->parent->r == t)) {
  161. return 1;
  162. }
  163. return 0;
  164. }
  165.  
  166. int main() {
  167. // srand(time(nullptr));
  168. ios_base::sync_with_stdio(0);
  169. cin.tie(0);
  170. cout.tie(0);
  171. item *root = nullptr;
  172. int n, q, m, el;
  173. cin >> n >> q >> m;
  174. for (int i = 0; i < n; ++i) {
  175. a[i] = new item(i, rr());
  176. }
  177. for (int i = 0; i < q; ++i) {
  178. int fr, to;
  179. cin >> fr >> to;
  180. fr--, to--;
  181. item *r1 = get_root(a[fr]);
  182. item *r2 = get_root(a[to]);
  183. // print(r1);
  184. // cout << endl;
  185. // print(r2);
  186. // cout << endl;
  187. if (r1 == r2) {
  188. r1->cycle = 1;
  189. } else {
  190. if (!the_biggest(a[fr])) {
  191. reverse(r1, 0, cnt(r1) - 1);
  192. }
  193. if (the_biggest(a[to])) {
  194. reverse(r2, 0, cnt(r2) - 1);
  195. }
  196. r1 = merge(r1, r2);
  197. }
  198. }
  199. for (int i = 0; i < m; ++i) {
  200. char tp;
  201. cin >> tp;
  202. int fr, to;
  203. cin >> fr >> to;
  204. fr--, to--;
  205. if (tp == '+') {
  206. item *r1 = get_root(a[fr]);
  207. item *r2 = get_root(a[to]);
  208. if (r1 == r2 && r1->cycle) {
  209. assert(0);
  210. return 0;
  211. }
  212. if (r1 == r2) {
  213. r1->cycle = 1;
  214. } else {
  215. if (!the_biggest(a[fr])) {
  216. reverse(r1, 0, cnt(r1) - 1);
  217. }
  218. if (the_biggest(a[to])) {
  219. reverse(r2, 0, cnt(r2) - 1);
  220. }
  221. r1 = merge(r1, r2);
  222. }
  223.  
  224. } else if (tp == '-') {
  225. item *r1 = get_root(a[fr]);
  226. int n1 = get_number(a[fr]);
  227. int n2 = get_number(a[to]);
  228. if (n1 > n2) {
  229. swap(fr, to);
  230. swap(n1, n2);
  231. // swap(r1, r2);
  232. }
  233.  
  234. if (r1->cycle) {
  235. if (abs(n1 - n2) > 1) {
  236. r1->cycle = 0;
  237. continue;
  238. }
  239. auto v = split(r1, n1 + 1, 0);
  240. r1 = merge(v.second, v.first);
  241. r1->cycle = 0;
  242. } else if (!r1->cycle) {
  243. auto v = split(r1, n1 + 1, 0);
  244. } else {
  245. // assert(0);
  246. // return 0;
  247. }
  248. // cout << "result " << endl;
  249. // print(r1);
  250. // cout << endl;
  251. // print(r2);
  252. // cout << endl;
  253. } else {
  254. int n1 = get_number(a[fr]);
  255. int n2 = get_number(a[to]);
  256.  
  257. item *r1 = get_root(a[fr]);
  258. item *r2 = get_root(a[to]);
  259. if (r1 == r2) {
  260. if (r1->cycle) {
  261. cout << max(min(abs(n1 - n2), cnt(r1) - abs(n1 - n2)) - 1, 0) << '\n';
  262. } else {
  263. cout << max(0, abs(n1 - n2) - 1) << '\n';
  264. }
  265. } else {
  266. cout << -1 << '\n';
  267. }
  268. }
  269. }
  270. // print(root);
  271. return 0;
  272. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement