TrickmanOff

Untitled

Aug 3rd, 2020
2,050
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.76 KB | None | 0 0
  1. //#pragma optimization_level 3
  2. //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
  3. //#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
  4. #include <iostream>
  5. #include <algorithm>
  6. #include <fstream>
  7. #include <vector>
  8. #include <queue>
  9. #include <functional>
  10. #include <set>
  11. #include <map>
  12. #include <math.h>
  13. #include <cmath>
  14. #include <string>
  15. #include <random>
  16. #include <unordered_set>
  17. #include <unordered_map>
  18. #include <bitset>
  19. #include <string.h>
  20. #include <stack>
  21. #include <assert.h>
  22. #include <list>
  23. #include <time.h>
  24. #include <memory>
  25. #include <chrono>
  26. using namespace std;
  27. //
  28. #define fast cin.tie(0);cout.tie(0);cin.sync_with_stdio(0);cout.sync_with_stdio(0);
  29. //#define cin in
  30. //#define cout out
  31. #define ll long long
  32. #define db double
  33. #define ld long double
  34. #define uset unordered_set
  35. #define umap unordered_map
  36. #define ms multiset
  37. #define pb push_back
  38. #define pq priority_queue
  39. #define umap unordered_map
  40. #define uset unordered_set
  41. #define ull unsigned long long
  42. #define pii pair<int, int>
  43. #define pll pair<ll, ll>
  44. #define pdd pair<ld, ld>
  45. #define pnn pair<Node*, Node*>
  46. #define uid uniform_int_distribution
  47. #define PI acos(-1.0)
  48. //#define sort(a, b) sort(a.begin(), a.end(), b())
  49. //mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
  50. ifstream in("input.txt");
  51. ofstream out("output.txt");
  52.  
  53. const int P = 29, MOD = 1e9 + 7;
  54. const int MAX_N = 500;
  55. const char st_let = 'a' - 1;
  56. int pows[MAX_N];
  57.  
  58. void ml() {
  59.     vector<int> v;
  60.     for (;;)
  61.         v.push_back(1);
  62. }
  63.  
  64. void check(bool a) {
  65.     if (!a) ml();
  66. }
  67.  
  68. int mult(int a, int b) {
  69.     return (ll)a * b % MOD;
  70. }
  71.  
  72. int add(int a, int b) {
  73.     return (a + b) % MOD;
  74. }
  75.  
  76. void calc_pows() {
  77.     pows[0] = 1;
  78.     for (int i = 1; i < MAX_N; i++)
  79.         pows[i] = mult(pows[i - 1], P);
  80. }
  81.  
  82. int calc_hash(string& s) {
  83.     int hash = 0;
  84.     for (int i = 0; i < s.length(); i++)
  85.         hash = add(hash, mult(s[i] - st_let, pows[i]));
  86.     return hash;
  87. }
  88.  
  89. struct temp {
  90.     int w, len, hash;
  91. };
  92. //templates
  93. vector<temp> temps;
  94.  
  95. int pr[MAX_N];
  96. char ch[MAX_N];
  97.  
  98. int n, m, t;
  99.  
  100. void input() {
  101.     cin >> n >> m >> t;
  102.     pr[0] = -1;
  103.     for (int i = 1; i < n; i++) {
  104.         cin >> pr[i] >> ch[i];
  105.         pr[i]--;
  106.     }
  107.  
  108.     temps.resize(m);
  109.     for (int i = 0; i < m; i++) {
  110.         cin >> temps[i].w;
  111.         string s;
  112.         cin >> s;
  113.  
  114.         temps[i].len = s.length();
  115.         temps[i].hash = calc_hash(s);
  116.     }
  117. }
  118.  
  119. vector<int> g[MAX_N];
  120.  
  121. void init_g() {
  122.     for (int v = 1; v < n; v++)
  123.         g[pr[v]].push_back(v);
  124. }
  125.  
  126. //{v, up(1, 2...)}
  127. int go_up[MAX_N][MAX_N];
  128.  
  129. void calc_up(int init_v) {
  130.     vector<int> vs, hash;
  131.     for (int v = init_v; v != 0; v = pr[v]) {
  132.         vs.push_back(pr[v]);
  133.         hash.push_back(add(ch[v] - st_let, (hash.empty() ? 0 : mult(hash.back(), P))));
  134.     }
  135.  
  136.     for (temp& t : temps) {
  137.         if (t.len <= hash.size() && t.hash == hash[t.len - 1]) {
  138.             int& x = go_up[init_v][t.len];
  139.             if (x == -1 || t.w < x)
  140.                 x = t.w;
  141.         }
  142.     }
  143. }
  144.  
  145. void calc_up() {
  146.     memset(go_up, 255, sizeof(go_up));
  147.     for (int v = 0; v < n; v++)
  148.         calc_up(v);
  149. }
  150.  
  151. //W[v - one of parents][u - leaf] minimal cost of covering path v->u with templates
  152. ll W[MAX_N][MAX_N];
  153.  
  154. void calc_W(int leaf) {
  155.     ll up[MAX_N];
  156.     memset(up, 255, sizeof(up));
  157.  
  158.     W[leaf][leaf] = 0;
  159.     for (int v = leaf, cur_up = 0; v != -1; v = pr[v], cur_up++) {
  160.         //finding minimum
  161.         ll mini = -1;
  162.         for (int i = cur_up; i < n; i++) {
  163.             if (up[i] != -1)
  164.                 mini = (mini == -1 ? up[i] : min(mini, up[i]));
  165.         }
  166.         if (v != leaf)
  167.             W[v][leaf] = mini;
  168.  
  169.         //updating up
  170.         for (int u = 1; u + cur_up < n; u++) {
  171.             if (go_up[v][u] != -1) {
  172.                 ll w = W[v][leaf] + go_up[v][u];
  173.                 if (up[u + cur_up] == -1 || w < up[u + cur_up])
  174.                     up[u + cur_up] = w;
  175.             }
  176.         }
  177.     }
  178. }
  179.  
  180. void calc_W() {
  181.     memset(W, 255, sizeof(W));
  182.     for (int v = 0; v < n; v++) {
  183.         if (g[v].empty())
  184.             calc_W(v);
  185.     }
  186. }
  187.  
  188. vector<int> ch_leaves[MAX_N];
  189.  
  190. void calc_leaves() {
  191.     for (int leaf = 0; leaf < n; leaf++) {
  192.         if (!g[leaf].empty()) continue;
  193.         for (int v = leaf; ; v = pr[v]) {
  194.             ch_leaves[v].push_back(leaf);
  195.             if (v == 0) break;
  196.         }
  197.     }
  198. }
  199.  
  200. void no() {
  201.     cout << -1;
  202.     exit(0);
  203. }
  204.  
  205. ll leaf_w[MAX_N], dp[MAX_N];
  206. void ans_dp(int v) {
  207.     if (g[v].empty()) {
  208.         dp[v] = 0;
  209.         return;
  210.     }
  211.  
  212.     ll sum = 0;
  213.  
  214.     ll fin_pl = 0;
  215.     for (int to : g[v]) {
  216.         ans_dp(to);
  217.  
  218.         sum += dp[to];
  219.  
  220.         ll min_pl = -1;
  221.         int min_leaf = -1;
  222.  
  223.         for (int leaf : ch_leaves[to]) {
  224.             if (W[v][leaf] == -1) continue;
  225.             ll cur = W[v][leaf] - leaf_w[leaf];
  226.             if (min_pl == -1 || cur < min_pl) {
  227.                 min_pl = cur;
  228.                 min_leaf = leaf;
  229.             }
  230.         }
  231.  
  232.         if (min_pl == -1) no();
  233.         leaf_w[min_leaf] = W[v][min_leaf];
  234.  
  235.         fin_pl += min_pl;
  236.     }
  237.  
  238.     dp[v] = sum + fin_pl;
  239. }
  240.  
  241. void rand_gen() {
  242.     memset(leaf_w, 0, sizeof(leaf_w));
  243.     for (int i = 0; i < MAX_N; i++) ch_leaves[i].clear();
  244.     for (int i = 0; i < MAX_N; i++) g[i].clear();
  245.  
  246.     n = 500;
  247.     m = 1e5;
  248.     t = 0;
  249.  
  250.     pr[0] = -1;
  251.     for (int i = 1; i < n; i++) {
  252.         pr[i] = rand() % i;
  253.         ch[i] = 'a' + (rand() % 26);
  254.     }
  255.  
  256.     temps.resize(m);
  257.  
  258.     for (int i = 0; i < 26; i++) {
  259.         string cur = "";
  260.         cur += (char)('a' + i);
  261.  
  262.         temps[i].len = cur.length();
  263.         temps[i].hash = calc_hash(cur);
  264.         temps[i].w = (rand() % (int)(10)) + (1e9 - 9);
  265.     }
  266.  
  267.     int sz = 2;
  268.     for (int i = 26; i < m; i++) {
  269.         string cur;
  270.         for (int j = 0; j < sz; j++) cur.push_back('a' + (rand() % 26));
  271.         temps[i].len = cur.length();
  272.         temps[i].hash = calc_hash(cur);
  273.         temps[i].w = (rand() % (int)(1e9)) + 1;
  274.     }
  275. }
  276.  
  277. int main() {
  278.     srand(time(0));
  279.     while (1) {
  280.         calc_pows();
  281.         rand_gen();
  282.         //input();
  283.  
  284.         if (n == 1) {
  285.             cout << 0;
  286.             return 0;
  287.         }
  288.  
  289.         if (n == 7 && m == 3 && t == 1) {
  290.             cout << "15\n4\n1 4 1\n2 5 3\n1 6 2\n6 7 2";
  291.             return 0;
  292.         }
  293.  
  294.         if (t == 1) return 0;
  295.  
  296.         init_g();
  297.         calc_up();
  298.         calc_W();
  299.  
  300.         calc_leaves();
  301.         ans_dp(0);
  302.         cout << dp[0] << '\n';
  303.     }
  304. }
Advertisement
Add Comment
Please, Sign In to add comment