Dang_Quan_10_Tin

RECOVER 27.12.2021

Dec 27th, 2021
1,235
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.72 KB | None | 0 0
  1. #define task "RECOVER"
  2.  
  3. #include <iostream>
  4. #include <cstdio>
  5.  
  6. using namespace std;
  7.  
  8. constexpr int N = 5e3 + 5;
  9. constexpr int mod = 2017;
  10. string s;
  11. int n, f[N][N], g[N][N], lcp[N][N];
  12.  
  13. void Read()
  14. {
  15.     cin >> s;
  16.     n = s.size();
  17.     s = " " + s;
  18. }
  19.  
  20. /* Subtask 2*/
  21.  
  22. bool Compare(const string &x, const string &y) // Kiểm tra liệu số x <= y
  23. {
  24.     if (x.size() < y.size())
  25.         return true;
  26.     if (x.size() > y.size())
  27.         return false;
  28.  
  29.     for (int i = 0; i < (int)x.size(); ++i)
  30.         if (x[i] < y[i])
  31.             return true;
  32.         else if (x[i] > y[i])
  33.             return false;
  34.  
  35.     return false; // x == y
  36. }
  37.  
  38. void Sub_2()
  39. {
  40.     for (int i = 1; i <= n; ++i)
  41.     {
  42.         f[i][1] = s[1] == '0' ? 0 : 1; // Nếu đây là số đầu tiên
  43.         for (int j = 2; j <= i; ++j)
  44.             if (s[j] != '0') // Số dương không bắt đầu bởi 0
  45.                 for (int t = 1; t < j; ++t)
  46.                     if (s[t] != '0') // Số dương không bắt đầu bởi 0
  47.                         if (Compare(s.substr(t, j - t), s.substr(j, i - j + 1)))
  48.                             (f[i][j] += f[j - 1][t]) %= mod;
  49.     }
  50. }
  51.  
  52. /*End subtask 2*/
  53.  
  54. /*Subtask 3*/
  55.  
  56. void Sub_3()
  57. {
  58.     for (int i = n; i; --i)
  59.         for (int j = n; j; --j)
  60.             if (s[i] == s[j])
  61.                 lcp[i][j] = lcp[i + 1][j + 1] + 1;
  62.             else
  63.                 lcp[i][j] = 0;
  64.  
  65.     for (int i = 1; i <= n; ++i)
  66.     {
  67.         f[i][1] = s[1] == '0' ? 0 : 1; // Nếu đây là số đầu tiên
  68.         for (int j = 2; j <= i; ++j)
  69.             if (s[j] != '0') // Số dương không bắt đầu bởi 0
  70.                 for (int t = 1; t < j; ++t)
  71.                     if (s[t] != '0') // Số dương không bắt đầu bởi 0
  72.                     {
  73.                         if (j - t > i - j + 1)
  74.                             ;
  75.                         else if (j - t < i - j + 1)
  76.                             (f[i][j] += f[j - 1][t]) %= mod;
  77.                         else if (lcp[j][t] < j - t && s[t + lcp[j][t]] < s[j + lcp[j][t]]) // So sánh thứ tự từ điển
  78.                             (f[i][j] += f[j - 1][t]) %= mod;
  79.                     }
  80.     }
  81. }
  82.  
  83. /*End subtask 3*/
  84.  
  85. /*Subtask 4*/
  86.  
  87. void Sub_4()
  88. {
  89.     for (int i = n; i; --i)
  90.         for (int j = n; j; --j)
  91.             if (s[i] == s[j])
  92.                 lcp[i][j] = lcp[i + 1][j + 1] + 1;
  93.             else
  94.                 lcp[i][j] = 0;
  95.  
  96.     for (int i = 1; i <= n; ++i)
  97.     {
  98.         f[i][1] = s[1] == '0' ? 0 : 1; // Nếu đây là số đầu tiên
  99.         g[i][1] = f[i][1];
  100.  
  101.         for (int j = 2; j <= i; ++j)
  102.         {
  103.             if (s[j] != '0') // Số dương không bắt đầu bởi 0
  104.             {
  105.                 f[i][j] = (g[j - 1][j - 1] - g[j - 1][max(0, j - 1 - (i - j))]) % mod;
  106.  
  107.                 if (j - 1 > i - j)
  108.                 {
  109.                     int t = j - 1 - (i - j);
  110.                     if (s[t] != '0' && lcp[j][t] < j - t && s[t + lcp[j][t]] < s[j + lcp[j][t]]) // So sánh thứ tự từ điển
  111.                         (f[i][j] += f[j - 1][t]) %= mod;
  112.                 }
  113.             }
  114.             g[i][j] = (g[i][j - 1] + f[i][j]) % mod;
  115.         }
  116.     }
  117. }
  118.  
  119. /*End subtask 4*/
  120.  
  121. void Print()
  122. {
  123.     int ans(0);
  124.  
  125.     for (int i = 1; i <= n; ++i)
  126.         (ans += f[n][i]) %= mod;
  127.  
  128.     cout << (ans + mod) % mod;
  129. }
  130.  
  131. int32_t main()
  132. {
  133.     ios::sync_with_stdio(0);
  134.     cin.tie(0);
  135.     cout.tie(0);
  136.     if (fopen(task ".INP", "r"))
  137.     {
  138.         freopen(task ".INP", "r", stdin);
  139.         freopen(task ".OUT", "w", stdout);
  140.     }
  141.  
  142.     Read();
  143.  
  144.     if (n <= 100)
  145.         Sub_2();
  146.     else if (n <= 400)
  147.         Sub_3();
  148.     else
  149.         Sub_4();
  150.  
  151.     Print();
  152. }
  153.  
Advertisement
Add Comment
Please, Sign In to add comment