Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define task "RECOVER"
- #include <iostream>
- #include <cstdio>
- using namespace std;
- constexpr int N = 5e3 + 5;
- constexpr int mod = 2017;
- string s;
- int n, f[N][N], g[N][N], lcp[N][N];
- void Read()
- {
- cin >> s;
- n = s.size();
- s = " " + s;
- }
- /* Subtask 2*/
- bool Compare(const string &x, const string &y) // Kiểm tra liệu số x <= y
- {
- if (x.size() < y.size())
- return true;
- if (x.size() > y.size())
- return false;
- for (int i = 0; i < (int)x.size(); ++i)
- if (x[i] < y[i])
- return true;
- else if (x[i] > y[i])
- return false;
- return false; // x == y
- }
- void Sub_2()
- {
- for (int i = 1; i <= n; ++i)
- {
- f[i][1] = s[1] == '0' ? 0 : 1; // Nếu đây là số đầu tiên
- for (int j = 2; j <= i; ++j)
- if (s[j] != '0') // Số dương không bắt đầu bởi 0
- for (int t = 1; t < j; ++t)
- if (s[t] != '0') // Số dương không bắt đầu bởi 0
- if (Compare(s.substr(t, j - t), s.substr(j, i - j + 1)))
- (f[i][j] += f[j - 1][t]) %= mod;
- }
- }
- /*End subtask 2*/
- /*Subtask 3*/
- void Sub_3()
- {
- for (int i = n; i; --i)
- for (int j = n; j; --j)
- if (s[i] == s[j])
- lcp[i][j] = lcp[i + 1][j + 1] + 1;
- else
- lcp[i][j] = 0;
- for (int i = 1; i <= n; ++i)
- {
- f[i][1] = s[1] == '0' ? 0 : 1; // Nếu đây là số đầu tiên
- for (int j = 2; j <= i; ++j)
- if (s[j] != '0') // Số dương không bắt đầu bởi 0
- for (int t = 1; t < j; ++t)
- if (s[t] != '0') // Số dương không bắt đầu bởi 0
- {
- if (j - t > i - j + 1)
- ;
- else if (j - t < i - j + 1)
- (f[i][j] += f[j - 1][t]) %= mod;
- 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
- (f[i][j] += f[j - 1][t]) %= mod;
- }
- }
- }
- /*End subtask 3*/
- /*Subtask 4*/
- void Sub_4()
- {
- for (int i = n; i; --i)
- for (int j = n; j; --j)
- if (s[i] == s[j])
- lcp[i][j] = lcp[i + 1][j + 1] + 1;
- else
- lcp[i][j] = 0;
- for (int i = 1; i <= n; ++i)
- {
- f[i][1] = s[1] == '0' ? 0 : 1; // Nếu đây là số đầu tiên
- g[i][1] = f[i][1];
- for (int j = 2; j <= i; ++j)
- {
- if (s[j] != '0') // Số dương không bắt đầu bởi 0
- {
- f[i][j] = (g[j - 1][j - 1] - g[j - 1][max(0, j - 1 - (i - j))]) % mod;
- if (j - 1 > i - j)
- {
- int t = j - 1 - (i - j);
- 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
- (f[i][j] += f[j - 1][t]) %= mod;
- }
- }
- g[i][j] = (g[i][j - 1] + f[i][j]) % mod;
- }
- }
- }
- /*End subtask 4*/
- void Print()
- {
- int ans(0);
- for (int i = 1; i <= n; ++i)
- (ans += f[n][i]) %= mod;
- cout << (ans + mod) % mod;
- }
- int32_t main()
- {
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- if (fopen(task ".INP", "r"))
- {
- freopen(task ".INP", "r", stdin);
- freopen(task ".OUT", "w", stdout);
- }
- Read();
- if (n <= 100)
- Sub_2();
- else if (n <= 400)
- Sub_3();
- else
- Sub_4();
- Print();
- }
Advertisement
Add Comment
Please, Sign In to add comment