mr_dot_convict

11022-String-Factoring-UVa.mr.convict

Jul 26th, 2019
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.72 KB | None | 0 0
  1. // Hack it and have it ;) //
  2. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  3.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  4.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  5.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  6.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  7. When I wrote this, only God and I understood what I was doing
  8.  ** * * * * * * * Now, only God knows * * * * * * */
  9. #include      <bits/stdc++.h>
  10. #include      <ext/pb_ds/assoc_container.hpp>
  11. #include      <ext/pb_ds/tree_policy.hpp>
  12. using namespace std;
  13. using namespace __gnu_pbds;
  14. #pragma GCC   optimize ("Ofast")
  15. #pragma GCC   optimize ("unroll-loops")
  16. #pragma GCC   target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  17.  
  18. #define IOS   ios_base::sync_with_stdio(false); cin.tie (nullptr)
  19. #define PREC  cout.precision (10); cout << fixed
  20. #define x     first
  21. #define y     second
  22. #define bg(x) " [ " << #x << " : " << (x) << " ] "
  23. #define un(x) sort(x.begin(), x.end()), \
  24.               x.erase(unique(x.begin(), x.end()), x.end())
  25. using   ll  = long long;
  26. using   ull = unsigned long long;
  27. using   ff  = long double;
  28. using   pii = pair<int,int>;
  29. using   pil = pair<int,ll>;
  30. typedef tree
  31. < int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
  32. ordered_set;
  33.  
  34. struct chash {
  35.    int operator()(pii x) const { return x.x*31 + x.y; }
  36. };
  37. gp_hash_table <pii, int, chash> mp;
  38.  
  39. //seed_seq seq{
  40. //   (uint64_t) chrono::duration_cast<chrono::nanoseconds>
  41. //      (chrono::high_resolution_clock::now().time_since_epoch()).count(),
  42. //      (uint64_t) __builtin_ia32_rdtsc(),
  43. //      (uint64_t) (uintptr_t) make_unique<char>().get()
  44. //};
  45. //mt19937 rng(seq); //uniform_int_distribution<int> (l, h)(rng); //[low, high]
  46. //
  47. #define debug(args...) { \
  48.    /* WARNING : do NOT compile this debug func calls with following flags: // \
  49.     * // -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_FORTIFY_SOURCE=2*/ \
  50.    string _s = #args; replace(_s.begin(), _s.end(), ',', ' ');\
  51.    stringstream _ss(_s); \
  52.    istream_iterator<string> _it(_ss); err(_it, args); \
  53. }
  54. void err(istream_iterator<string> it) {
  55.    it->empty(); cerr << " (Line : " << __LINE__ << ")" << '\n';
  56. }
  57. template<typename T, typename... Args>
  58. void err(istream_iterator<string> it, T a, Args... args) {
  59.    cerr << fixed << setprecision(15)
  60.       << " [ " <<  *it << " : " << a  << " ] "<< ' ';
  61.    err(++it, args...);
  62. }
  63. /*****************************************************************************/
  64.  
  65. const int N = (int)1e5 + 10;
  66. int n;
  67. string s;
  68. int pi[N];
  69.  
  70. void pref_func (string &st) {
  71.    pi[0] = 0;
  72.    int sz = (int)st.size();
  73.    for (int i = 1; i < sz; ++i) {
  74.       int len_j = pi[i-1]; // length of perfect prefix for i
  75.       int j = len_j - 1; // index of end of perfect prefix for i
  76.       while (len_j > 0 && st[j + 1] != st[i]) {
  77.          len_j = pi[j];
  78.          j = len_j - 1;
  79.       }
  80.       if (st[len_j] == st[i])
  81.          ++len_j;
  82.       pi[i] = len_j;
  83.    }
  84. }
  85.  
  86. int rec(int x, int y) {
  87.    int l = y + 1 - x;
  88.    vector <int> dp (l);
  89.    for (int i = 0; i < l; ++i) {
  90.       dp[i] = i + 1;
  91.       string sub = s.substr(x, i + 1);
  92.       reverse(sub.begin(), sub.end());
  93.       pref_func(sub);
  94.  
  95.       for (int j = 0; j <= i; ++j) {
  96.          int len = i + 1 - j;
  97.          int k = len - pi[len - 1];
  98.          if (pi[len - 1] != 0 && len % k == 0) {
  99.             dp[i] = min(dp[i], rec(x + j, x + j + k - 1) + (j != 0 ? dp[j - 1] : 0));
  100.          }
  101.          else {
  102.             dp[i] = min(dp[i], len + (j != 0 ? dp[j - 1] : 0));
  103.          }
  104.       }
  105.    }
  106.    return dp[l - 1];
  107. }
  108.  
  109.  
  110. signed main() {
  111.    IOS; PREC;
  112.    while (cin >> s, s != "*") {
  113.       n = (int)s.size();
  114.       cout << rec(0, n - 1) << '\n';
  115.    }
  116.  
  117.    return EXIT_SUCCESS;
  118. }
Add Comment
Please, Sign In to add comment