Advertisement
GerONSo

poor euler tour tree

Nov 7th, 2019
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.22 KB | None | 0 0
  1. /*
  2.  
  3. ∧_∧
  4. ( ・ω・。)つ━☆・*。
  5. ⊂  ノ    ・゜
  6. しーJ   Accepted
  7.  
  8. */
  9.  
  10.  
  11.  
  12. // #pragma GCC optimize("O3")
  13. // #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  14.  
  15. #include <bits/stdc++.h>
  16. #include <ext/pb_ds/assoc_container.hpp>
  17. #include <ext/pb_ds/tree_policy.hpp>
  18.  
  19. #define ll long long
  20. #define all(x) begin(x), end(x)
  21. #define x first
  22. #define y second
  23. // #define int long long
  24.  
  25. using namespace std;
  26. using namespace __gnu_pbds;
  27.  
  28. typedef long double ld;
  29. template<typename T>
  30. using kawaii_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
  31.  
  32. const ld PI = atan2(0, -1);
  33.  
  34. void seriy() {
  35. ios::sync_with_stdio(0);
  36. cin.tie(0);
  37. cout.tie(0);
  38. cout << fixed << setprecision(14);
  39. #ifdef _offline
  40. freopen("input.txt", "r", stdin);
  41. freopen("output.txt", "w", stdout);
  42. #endif
  43. }
  44.  
  45. const int MAXN = 1e6 + 10;
  46. const int MAXM = 600;
  47. const int INF = 1e18;
  48. const int BASE = 47;
  49. const int MOD = 1e9 + 7;
  50. const int MAXLOG = 21;
  51.  
  52. mt19937 rr(time(0));
  53.  
  54. struct treap {
  55. treap *left = nullptr;
  56. treap *right = nullptr;
  57. treap *parent = nullptr;
  58. int prior, sz, val;
  59. bool reversed = 0, cycle = 0;
  60.  
  61. treap(int val) {
  62. this->val = val;
  63. this->prior = rr();
  64. this->sz = 1;
  65. }
  66. };
  67.  
  68. vector<vector<int>> g;
  69. vector<treap*> links;
  70.  
  71.  
  72. int get_size(treap *&root) {
  73. return ((root == nullptr) ? 0 : root->sz);
  74. }
  75.  
  76. int get_val(treap *&root) {
  77. return ((root == nullptr) ? -1 : root->val);
  78. }
  79.  
  80. int get_rev(treap *&root) {
  81. return ((root == nullptr) ? -1 : root->reversed);
  82. }
  83.  
  84. void print(treap *a) {
  85. if(a->left != nullptr) print(a->left);
  86. cerr << get_val(a) << " " << get_rev(a) << " " << get_val(a->left) << " " << get_val(a->right) << '\n';
  87. if(a->right != nullptr) print(a->right);
  88. }
  89.  
  90. void update(treap *&root) {
  91. if(root == nullptr) return;
  92. root->sz = get_size(root->left) + get_size(root->right) + 1;
  93. if(root->left != nullptr) {
  94. root->left->parent = root;
  95. }
  96. if(root->right != nullptr) {
  97. root->right->parent = root;
  98. }
  99. }
  100.  
  101. void push(treap *&root) {
  102. if(root == nullptr || root->reversed == 0) {
  103. return;
  104. }
  105. if(root->left != nullptr) {
  106. root->left->reversed ^= 1;
  107. }
  108. if(root->right != nullptr) {
  109. root->right->reversed ^= 1;
  110. }
  111. swap(root->left, root->right);
  112. root->reversed = 0;
  113. }
  114.  
  115. pair<treap*, treap*> split(treap *&root, int key) {
  116. push(root);
  117. if(root == nullptr) {
  118. return {nullptr, nullptr};
  119. }
  120. int root_key = get_size(root->left);
  121. // cerr << root->sz << " " << root_key << '\n';
  122. if(key > root_key) {
  123. pair<treap*, treap*> splitted = split(root->right, key - get_size(root->left) - 1);
  124. root->right = splitted.x;
  125. update(root);
  126. return {root, splitted.y};
  127. }
  128. else {
  129. pair<treap*, treap*> splitted = split(root->left, key);
  130. root->left = splitted.y;
  131. update(root);
  132. return {splitted.x, root};
  133. }
  134. }
  135.  
  136. treap* merge(treap *&left, treap *&right) {
  137. push(left);
  138. push(right);
  139. if(left == nullptr) {
  140. return right;
  141. }
  142. if(right == nullptr) {
  143. return left;
  144. }
  145. if(left->prior > right->prior) {
  146. left->right = merge(left->right, right);
  147. update(left);
  148. return left;
  149. }
  150. else {
  151. right->left = merge(left, right->left);
  152. update(right);
  153. return right;
  154. }
  155. }
  156.  
  157. treap* get(treap *&root, int pos) {
  158. push(root);
  159. if(pos < get_size(root->left)) {
  160. return get(root->left, pos);
  161. }
  162. else if(pos > get_size(root->left)) {
  163. return get(root->right, pos - get_size(root->left) - 1);
  164. }
  165. else {
  166. return root;
  167. }
  168. }
  169.  
  170. void reverse(treap *&root, int l, int r) {
  171. pair<treap*, treap*> a = split(root, r);
  172. pair<treap*, treap*> b = split(a.x, l);
  173. b.y->reversed ^= 1;
  174. b.x = merge(b.x, b.y);
  175. root = merge(b.x, a.y);
  176. }
  177.  
  178. void insert(treap *&root, int pos, int val) {
  179. pair<treap*, treap*> splitted = split(root, pos);
  180. treap *nw = new treap(val);
  181. splitted.x = merge(splitted.x, nw);
  182. update(splitted.x);
  183. splitted.x = merge(splitted.x, splitted.y);
  184. update(splitted.x);
  185. root = splitted.x;
  186. }
  187.  
  188. vector<vector<int>> bamboos, cycles;
  189. vector<bool> used;
  190. vector<int> cur;
  191. bool is_cyc = 0;
  192.  
  193. void dfs(int u) {
  194. used[u] = 1;
  195. cur.push_back(u);
  196. for(auto v : g[u]) {
  197. if(!used[v]) {
  198. dfs(v);
  199. }
  200. else {
  201. is_cyc = 1;
  202. }
  203. }
  204. }
  205.  
  206. vector<int> where;
  207.  
  208. treap* get_root(treap *&a) {
  209. if(a->parent == nullptr) {
  210. return a;
  211. }
  212. return get_root(a->parent);
  213. }
  214.  
  215. treap* get_root2(treap *&a) {
  216. if(a->parent == nullptr) {
  217. return a;
  218. }
  219. if(a->parent->right == a) {
  220. where.push_back(1);
  221. }
  222. else {
  223. where.push_back(-1);
  224. }
  225. return get_root2(a->parent);
  226. }
  227.  
  228. void recalc(treap *&a, int cur) {
  229. if(a->reversed) {
  230. cur *= -1;
  231. }
  232. push(a);
  233. // cerr << get_val(a) << '\n';
  234. if(where.size() == 0) {
  235. return;
  236. }
  237. int back = where.back() * cur;
  238. where.pop_back();
  239. if(back > 0) {
  240. recalc(a->right, 1);
  241. }
  242. else {
  243. recalc(a->left, 1);
  244. }
  245. }
  246.  
  247. int get_pos(treap *&a) {
  248. if(a == nullptr) {
  249. return 0;
  250. }
  251. // cerr << a->val << " ";
  252. int ans = 0;
  253. if(a->parent != nullptr && a->parent->right == a) {
  254. ans += get_size(a->parent->left) + 1;
  255. }
  256. return ans + get_pos(a->parent);
  257. }
  258.  
  259. treap* lefter(treap *&a) {
  260. push(a);
  261. if(a->left == nullptr) {
  262. return a;
  263. }
  264. return lefter(a->left);
  265. }
  266.  
  267. treap* righter(treap *&a) {
  268. push(a);
  269. if(a->right == nullptr) {
  270. return a;
  271. }
  272. return righter(a->right);
  273. }
  274.  
  275. signed main() {
  276. seriy();
  277. int n, m, q;
  278. cin >> n >> m >> q;
  279. g.resize(n);
  280. used.resize(n);
  281. links.resize(n);
  282. for(int i = 0; i < m; i++) {
  283. int u, v;
  284. cin >> u >> v;
  285. u--;
  286. v--;
  287. g[u].push_back(v);
  288. g[v].push_back(u);
  289. }
  290. for(int i = 0; i < n; i++) {
  291. if(!used[i] && g[i].size() <= 1) {
  292. cur.clear();
  293. dfs(i);
  294. bamboos.push_back(cur);
  295. }
  296. }
  297. for(int i = 0; i < n; i++) {
  298. if(!used[i]) {
  299. cur.clear();
  300. dfs(i);
  301. cycles.push_back(cur);
  302. }
  303. }
  304. for(int i = 0; i < bamboos.size(); i++) {
  305. treap *start = nullptr;
  306. for(int j = 0; j < bamboos[i].size(); j++) {
  307. int cur = bamboos[i][j];
  308. insert(start, j, cur);
  309. links[bamboos[i][j]] = get(start, j);
  310. }
  311. }
  312.  
  313. // for(int i = 0; i < bamboos.size(); i++) {
  314. // for(auto j : bamboos[i]) {
  315. // cerr << j << " " << get_val(links[j]->parent) << '\n';
  316. // }
  317. // cerr << '\n';
  318. // }
  319.  
  320. for(int i = 0; i < cycles.size(); i++) {
  321. treap *start = nullptr;
  322. for(int j = 0; j < cycles[i].size(); j++) {
  323. int cur = cycles[i][j];
  324. insert(start, j, cur);
  325. links[cycles[i][j]] = get(start, j);
  326. }
  327. treap *root = get_root(links[cycles[i][0]]);
  328. root->cycle = 1;
  329. }
  330.  
  331. // for(int i = 0; i < cycles.size(); i++) {
  332. // for(auto j : cycles[i]) {
  333. // cerr << j << " " << get_val(links[j]->parent) << '\n';
  334. // }
  335. // cerr << '\n';
  336. // }
  337.  
  338. // cerr << '\n';
  339. while(q--) {
  340. char c;
  341. cin >> c;
  342. if(c == '?') {
  343. int a, b;
  344. cin >> a >> b;
  345. a--;
  346. b--;
  347. treap *r1 = get_root2(links[a]);
  348. recalc(r1, 1);
  349. treap *r2 = get_root2(links[b]);
  350. // print(r2);
  351. // cerr << '\n';
  352. // for(auto i : where) {
  353. // cerr << i << " ";
  354. // }
  355. // cerr << '\n';
  356. // cerr << 1;
  357. recalc(r2, 1);
  358. if(r1 == r2) {
  359. // print(r1);
  360. // cerr << '\n';
  361. int p1 = get_pos(links[a]) + get_size(links[a]->left);
  362. int p2 = get_pos(links[b]) + get_size(links[b]->left);
  363. if(p2 < p1) {
  364. swap(p1, p2);
  365. }
  366. // cerr << p1 << " " << p2 << '\n';
  367. int ans;
  368. treap *root = get_root(links[a]);
  369. if(root->cycle) {
  370. ans = min(p2 - p1, p1 + get_size(root) - p2);
  371. }
  372. else {
  373. ans = p2 - p1;
  374. }
  375. cout << max(ans - 1, 0) << '\n';
  376. }
  377. else {
  378. cout << -1 << '\n';
  379. }
  380. }
  381. else if(c == '+') {
  382. int a, b;
  383. cin >> a >> b;
  384. a--;
  385. b--;
  386. treap *root1 = get_root2(links[a]);
  387. recalc(root1, 1);
  388. treap *root2 = get_root2(links[b]);
  389. recalc(root2, 1);
  390.  
  391. if(root1 != root2) {
  392. treap *left1 = lefter(root1);
  393. treap *right1 = righter(root1);
  394. treap *left2 = lefter(root2);
  395. treap *right2 = righter(root2);
  396. // print(root1);
  397. // cerr << '\n';
  398.  
  399. if(get_val(right1) != a) {
  400. reverse(root1, -1, get_size(root1));
  401. }
  402. if(get_val(left2) != b) {
  403. reverse(root2, -1, get_size(root2));
  404. }
  405.  
  406. // print(root1);
  407. // cerr << '\n';
  408. root1 = merge(root1, root2);
  409. // print(root1);
  410. }
  411. else {
  412. root1->cycle = 1;
  413. }
  414. }
  415. else if(c == '-') {
  416. int a, b;
  417. cin >> a >> b;
  418. a--;
  419. b--;
  420. treap *root1 = get_root2(links[a]);
  421. recalc(root1, 1);
  422. treap *root2 = get_root2(links[b]);
  423. recalc(root2, 1);
  424. int p1 = get_pos(links[a]) + get_size(links[a]->left);
  425. int p2 = get_pos(links[b]) + get_size(links[b]->left);
  426. if(p1 > p2) {
  427. swap(p1, p2);
  428. }
  429. if(root1->cycle) {
  430. treap *left = lefter(root1);
  431. treap *right = righter(root1);
  432. root1->cycle = 0;
  433.  
  434. if(p1 > p2) {
  435. swap(p1, p2);
  436. }
  437. if(get_val(left) == a && get_val(right) == b || get_val(left) == b && get_val(right) == a) {
  438.  
  439. }
  440. else {
  441. reverse(root1, -1, p2);
  442. reverse(root1, p2, get_size(root1));
  443. }
  444. }
  445. else {
  446. pair<treap*, treap*> splitted = split(root1, p2);
  447. splitted.x->parent = nullptr;
  448. splitted.y->parent = nullptr;
  449. }
  450. }
  451. }
  452. return 0;
  453. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement