Advertisement
Mlxa

Персистентное ДО на кучу операций

Feb 1st, 2019
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.77 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. #define long ll
  5. #define all(x) begin(x), end(x)
  6.  
  7. const int M1  = 1e9 + 7;
  8. const int M2  = 1e9 + 33;
  9. const int MAX = 1e7 + 7;
  10. const int N   = 1e5 + 5;
  11.  
  12. int pow1[N + 1], pow2[N + 1];
  13.  
  14. struct Node {
  15.     Node *l, *r;
  16.     int h1, h2;
  17.     bool zero;
  18.     Node() :
  19.         l(nullptr),
  20.         r(nullptr),
  21.         h1(0),
  22.         h2(0),
  23.         zero(false) {}
  24. };
  25.  
  26. bool check_full(Node *t, int len) {
  27.     assert(t);
  28.     return t->h1 == (pow1[len] + M1 - 1) % M1 && t->h2 == (pow2[len] + M2 - 1) % M2;
  29. }
  30.  
  31. Node pool[MAX];
  32. int pool_ptr = 0;
  33.  
  34. __attribute__((warn_unused_result))
  35. Node *make_node() {
  36.     return pool + pool_ptr++;
  37. }
  38.  
  39. __attribute__((warn_unused_result))
  40. Node *clone_node(Node *v) {
  41.     assert(v);
  42.     Node *res   = make_node();
  43.     res->l      = v->l;
  44.     res->r      = v->r;
  45.     res->h1     = v->h1;
  46.     res->h2     = v->h2;
  47.     res->zero   = v->zero;
  48.     return res;
  49. }
  50.  
  51. void push(Node *t) {
  52.     if (t->zero) {
  53.         if (!t->l) {
  54.             t->l = make_node();
  55.         }
  56.         t->l->zero = true;
  57.         t->l->h1   = 0;
  58.         t->l->h2   = 0;
  59.         if (!t->r) {
  60.             t->r = make_node();
  61.         }
  62.         t->r->zero = true;
  63.         t->r->h1   = 0;
  64.         t->r->h2   = 0;
  65.     }
  66.     t->zero = false;
  67. }
  68.  
  69. __attribute__((warn_unused_result))
  70. Node *pull(Node *t, int l, int r) {
  71.     assert(l && r);
  72.     long l1 = 0, r1 = 0, l2 = 0, r2 = 0;
  73.     if (t->l) {
  74.         l1 = t->l->h1;
  75.         l2 = t->l->h2;
  76.     }
  77.     if (t->r) {
  78.         r1 = t->r->h1;
  79.         r2 = t->r->h2;
  80.     }
  81.     t->h1 = (int)((l1 + r1 * pow1[l]) % M1);
  82.     t->h2 = (int)((l2 + r2 * pow2[l]) % M2);
  83.     return t;
  84. }
  85.  
  86. __attribute__((warn_unused_result))
  87. Node *zero_range(Node *t, int vl, int vr, int ql, int qr) {
  88.     if (qr <= vl || vr <= ql || !t) {
  89.         return t;
  90.     }
  91.     t = clone_node(t);
  92.     if (ql <= vl && vr <= qr) {
  93.         t->zero = true;
  94.         t->h1   = 0;
  95.         t->h2   = 0;
  96.         return t;
  97.     }
  98.     int vm = (vl + vr) / 2;
  99.     push(t);
  100.     t->l = zero_range(t->l, vl, vm, ql, qr);
  101.     t->r = zero_range(t->r, vm, vr, ql, qr);
  102.     return pull(t, vm - vl, vr - vm);
  103. }
  104.  
  105. __attribute__((warn_unused_result))
  106. Node *one_point(Node *t, int vl, int vr, int qp) {
  107.     assert(vl <= qp && qp < vr);
  108.     if (!t) {
  109.         t = make_node();
  110.     } else {
  111.         t = clone_node(t);
  112.     }
  113.     if (vr - vl == 1) {
  114.         t->h1 = 1;
  115.         t->h2 = 1;
  116.         return t;
  117.     }
  118.     int vm = (vl + vr) / 2;
  119.     push(t);
  120.     if (qp < vm) {
  121.         t->l = one_point(t->l, vl, vm, qp);
  122.     } else {
  123.         t->r = one_point(t->r, vm, vr, qp);
  124.     }
  125.     return pull(t, vm - vl, vr - vm);
  126. }
  127.  
  128. __attribute__((warn_unused_result))
  129. pair<int, Node *> find_first_zero(Node *t, int vl, int vr, int ql) {
  130.     if (vr <= ql) {
  131.         return {-1, t};
  132.     }
  133.     if (!t) {
  134.         return {max(vl, ql), t};
  135.     }
  136.     if (check_full(t, vr - vl)) {
  137.         return {-1, t};
  138.     }
  139.     if (vr - vl == 1 && t->h1 == 0 && t->h2 == 0) {
  140.         return {vl, t};
  141.     }
  142.     t = clone_node(t);
  143.     int vm = (vl + vr) / 2;
  144.     push(t);
  145.     int answer;
  146.     tie(answer, t->l) = find_first_zero(t->l, vl, vm, ql);
  147.     if (answer != -1) {
  148.         return { answer, t };
  149.     }
  150.     tie(answer, t->r) = find_first_zero(t->r, vm, vr, ql);
  151.     return { answer, t };
  152. }
  153.  
  154. __attribute__((warn_unused_result))
  155. tuple<int, Node *, Node *> lcp(Node *a, Node *b, int vl, int vr) {
  156.     pair<int, int> hash_a(0, 0);
  157.     pair<int, int> hash_b(0, 0);
  158.     if (a) {
  159.         hash_a = make_pair(a->h1, a->h2);
  160.     }
  161.     if (b) {
  162.         hash_b = make_pair(b->h1, b->h2);
  163.     }
  164.    
  165.     if (hash_a == hash_b) {
  166.         return make_tuple(vr - vl, a, b);
  167.     }
  168.     if (vr - vl == 1) {
  169.         return make_tuple(0, a, b);
  170.     }
  171.     if (!a) {
  172.         a = make_node();
  173.     } else {
  174.         a = clone_node(a);
  175.     }
  176.     if (!b) {
  177.         b = make_node();
  178.     } else {
  179.         b = clone_node(b);
  180.     }
  181.     int vm = (vl + vr) / 2;
  182.     int answer;
  183.     push(a);
  184.     push(b);
  185.     tie(answer, a->r, b->r) = lcp(a->r, b->r, vm, vr);
  186.     if (answer == vr - vm) {
  187.         tie(answer, a->l, b->l) = lcp(a->l, b->l, vl, vm);
  188.         return make_tuple(vr - vm + answer, a, b);
  189.     }
  190.     return make_tuple(answer, a, b);
  191. }
  192.  
  193. __attribute__((warn_unused_result))
  194. pair<int, Node *> get_value(Node *t, int vl, int vr, int qp) {
  195.     assert(vl <= qp && qp < vr);
  196.     if (!t) {
  197.         return { 0, t };
  198.     }
  199.     if (vr - vl == 1) {
  200.         return { t->h1, t };
  201.     }
  202.     t = clone_node(t);
  203.     int vm = (vl + vr) / 2;
  204.     push(t);
  205.     int answer;
  206.     if (qp < vm) {
  207.         tie(answer, t->l) = get_value(t->l, vl, vm, qp);
  208.         return { answer, t };
  209.     } else {
  210.         tie(answer, t->r) = get_value(t->r, vm, vr, qp);
  211.         return { answer, t };
  212.     }
  213. }
  214.  
  215. __attribute__((warn_unused_result))
  216. Node *print(Node *t, int vl, int vr, int lim) {
  217.     if (vr - vl == 1) {
  218.         if (lim > 0) {
  219.             cout << (t && t->h1);
  220.         }
  221.         return t;
  222.     }
  223.     if (t) {
  224.         t = clone_node(t);
  225.         push(t);
  226.         int vm = (vl + vr) / 2;
  227.         t->r = print(t->r, vm, vr, lim - (vm - vl));
  228.         t->l = print(t->l, vl, vm, lim);
  229.     } else {
  230.         for (int i = vl; i < min(vr, vl + lim); ++i) {
  231.             cout << '0';
  232.         }
  233.     }
  234.     return t;
  235. }
  236.  
  237. void print(Node *&num, int lim) {
  238.     if (num) {
  239.         num = print(num, 0, N, lim);
  240.     } else {
  241.         while (lim--) {
  242.             cout << '0';
  243.         }
  244.     }
  245.     cout << endl;
  246. }
  247.  
  248. __attribute__((warn_unused_result))
  249. Node *add_power(Node *num, int p) {
  250.     int x;
  251.     tie(x, num) = find_first_zero(num, 0, N, p);
  252.     num = zero_range(num, 0, N, p, x);
  253.     num = one_point(num, 0, N, x);
  254.     return num;
  255. }
  256.  
  257. int get_mod(Node *t) {
  258.     if (t) {
  259.         return t->h1;
  260.     }
  261.     return 0;
  262. }
  263.  
  264. int compare(Node *&a, Node *&b) {
  265.     int l;
  266.     tie(l, a, b) = lcp(a, b, 0, N);
  267.     if (l == N) {
  268.         return 0;
  269.     }
  270.     l = N - l - 1;
  271.     int x, y;
  272.     tie(x, a) = get_value(a, 0, N, l);
  273.     tie(y, b) = get_value(b, 0, N, l);
  274.     if (x < y) {
  275.         return -1;
  276.     } else {
  277.         return +1;
  278.     }
  279. }
  280. bool cmp(Node *&a, Node *&b) {
  281.     return compare(a, b) == -1;
  282. }
  283. bool operator<(pair<Node *, int> &a, pair<Node *, int> &b) {
  284.     int res = compare(a.first, b.first);
  285.     if (res == 0) {
  286.         return a.second < b.second;
  287.     }
  288.     return res == -1;
  289. }
  290.  
  291. const int MOD   = 1e9 + 7;
  292. int n, m;
  293.  
  294. vector<pair<int, int>> g[N];
  295. Node *node_dist[N];
  296. int dist[N];
  297. int anc[N];
  298.  
  299.  
  300. int main() {
  301. #ifdef LC
  302.     //assert(freopen("input.txt", "r", stdin));
  303. #endif
  304.     ios::sync_with_stdio(false);
  305.     cin.tie(nullptr);
  306.    
  307.     pow1[0] = 1;
  308.     pow2[0] = 1;
  309.     for (int i = 1; i <= N; ++i) {
  310.         pow1[i] = (pow1[i - 1] * 2) % M1;
  311.         pow2[i] = (pow2[i - 1] * 2) % M2;
  312.     }
  313.    
  314.     cin >> n >> m;
  315.     for (int a, b, x, i = 0; i < m; ++i) {
  316.         cin >> a >> b >> x;
  317.         --a;
  318.         --b;
  319.         g[a].emplace_back(b, x);
  320.         g[b].emplace_back(a, x);
  321.     }
  322.     int start, finish;
  323.     cin >> start >> finish;
  324.     --start;
  325.     --finish;
  326.    
  327.     fill_n(dist, N, -1);
  328.     fill_n(anc, N, -1);
  329.     dist[start] = 0;
  330.    
  331.     set<pair<Node *, int>> q;
  332.    
  333.     q.emplace(nullptr, start);
  334.    
  335.     while (q.size()) {
  336.         pair<Node *, int> d_v = *q.begin();
  337.         Node *d;
  338.         if (d_v.first) {
  339.             d = clone_node(d_v.first);
  340.         } else {
  341.             d = make_node();
  342.         }
  343.         int v = d_v.second;
  344.         //cerr << "POP " << v + 1 << '\t';
  345.         //print(node_dist[v], 10);
  346.         //print(d, 10);
  347.        
  348.         q.erase(q.begin());
  349.         dist[v] = get_mod(d);
  350.         for (const auto &u_x : g[v]) {
  351.             Node *possible = add_power(d, u_x.second);
  352.             assert(possible);
  353.             if (dist[u_x.first] == -1 || compare(possible, node_dist[u_x.first]) == -1) {
  354.                 anc[u_x.first] = v;
  355.                 q.erase({ node_dist[u_x.first], u_x.first });
  356.                 node_dist[u_x.first] = clone_node(possible);
  357.                 dist[u_x.first] = 0;
  358.                 q.emplace(node_dist[u_x.first], u_x.first);
  359.             }
  360.         }
  361.     }
  362.    
  363.     cout << dist[finish] << '\n';
  364.     if (dist[finish] != -1) {
  365.         vector<int> path;
  366.         int v = finish;
  367.         while (v != -1) {
  368.             path.push_back(v);
  369.             v = anc[v];
  370.         }
  371.         cout << (int)path.size() << '\n';
  372.         reverse(all(path));
  373.         for (int e : path) {
  374.             cout << e + 1 << ' ';
  375.         }
  376.         cout << '\n';
  377.     }
  378.     /*cin >> n;
  379.     vector<Node *> arr(n);
  380.     for (int i = 0; i < n; ++i) {
  381.         int x;
  382.         cin >> x;
  383.         Node *num = nullptr;
  384.         while (x >= 0) {
  385.             num = add_power(num, x);
  386.             cin >> x;
  387.         }
  388.         arr[i] = num;
  389.     }
  390.    
  391.     sort(all(arr), cmp);
  392.    
  393.     for (int i = 0; i < n; ++i) {
  394.         cout << get_mod(arr[i]) << '\t';
  395.         print(arr[i], 50);
  396.     }*/
  397.    
  398.     return 0;
  399. }
  400.  
  401. /*
  402. 3
  403. 0 0 0 0 0 0 0 -1
  404. 1 1 1 -1
  405. 2 -1
  406. */
  407.  
  408. /*
  409. 9
  410. 100 -1
  411. 0 -1
  412. 0 0 0 0 -1
  413. 0 0 -1
  414. 0 0 0 -1
  415. 1 -1
  416. 2 -1
  417. 20 20 -1
  418. 10 -1
  419. * */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement