Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #include <iostream>
- #include <string>
- #include <vector>
- #include <algorithm>
- #include <utility>
- #include <set>
- #include <map>
- #include <unordered_map>
- #include <cassert>
- #include <cmath>
- #include <ctime>
- #include <queue>
- #include <memory.h>
- #include <stack>
- #include <bitset>
- using namespace std;
- typedef long long ll;
- typedef long double ld;
- vector < int > from_z_to_prefix(vector < int > z)
- {
- int r = -1;
- z[0] = 0;
- vector < int > p(z.size());
- for (int i = 0; i < z.size(); i++)
- {
- if (i + z[i] - 1 > r)
- {
- for (int pos = r + 1; pos <= i + z[i] - 1; pos++)
- {
- p[pos] = pos - i + 1;
- }
- r = i + z[i] - 1;
- }
- }
- return p;
- }
- vector < int > from_prefix_to_z(vector < int > p)
- {
- vector < int > z(p.size());
- z[0] = p.size();
- for (int i = 1; i < z.size(); i++)
- {
- if (p[i] != 0)
- {
- z[i - p[i] + 1] = max(p[i], z[i - p[i] + 1]);
- }
- }
- int pos = 1;
- while (pos < p.size())
- {
- int j;
- for (j = pos + 1; j < pos + z[pos] && z[j] <= z[pos] - (j - pos) && z[j - pos] >= z[j]; j++)
- {
- z[j] = min(z[pos] - (j - pos), z[j - pos]);
- }
- pos = j;
- }
- return z;
- }
- vector < int > read_vector(int n)
- {
- vector < int > v;
- for (int i = 0; i < n; i++)
- {
- int x;
- cin >> x;
- v.push_back(x);
- }
- return v;
- }
- void write_vector(vector < short > v)
- {
- for (int el : v)
- {
- cout << el;
- }
- cout << "\n";
- }
- struct Node
- {
- int next[30];
- //int last = 0;
- };
- vector < int > last;
- vector < int> prefix_function(string s)
- {
- vector < int > p(s.size());
- for (int i = 1; i < p.size(); i++)
- {
- int pos = p[i - 1];
- while (pos > 0 && s[pos] != s[i])
- {
- pos = p[pos - 1];
- }
- s[i] == s[pos] ? p[i] = pos + 1 : p[i] = 0;
- }
- return p;
- }
- vector < Node > build(string s)
- {
- vector < Node > p(s.size() + 1);
- last.resize(s.size() + 1);
- vector < int > pref = prefix_function(s);
- s = " " + s;
- for (int i = 0; i < s.size() - 1; i++)
- {
- for (char c = 'a'; c <= 'z'; c++)
- {
- if (i > 0 && s[i + 1] != c)
- {
- p[i].next[c - 'a'] = p[pref[i]].next[c - 'a'];
- last[p[pref[i]].next[c - 'a']] = max(last[p[pref[i]].next[c - 'a']], i);
- //p[p[pref[i]].next[c - 'a']].last = max(p[p[pref[i]].next[c - 'a']].last, i);
- continue;
- }
- if (s[i + 1] == c)
- {
- p[i].next[c - 'a'] = i + 1;
- //p[i + 1].last = max(i, p[i + 1].last);
- continue;
- }
- p[i].next[c - 'a'] = i;
- last[i] = max(i, last[i]);
- }
- }
- return p;
- }
- void norm(vector < short >& v)
- {
- while (!v.empty() && v.back() == 0)
- {
- v.pop_back();
- v.shrink_to_fit();
- }
- }
- vector < short > add(vector < short > v, vector < short > v1)
- {
- v.resize(max(v.size(), v1.size()));
- v1.resize(v.size());
- int per = 0;
- for (int i = 0; i < v.size(); i++)
- {
- v[i] += v1[i] + per;
- if (v[i] >= 10)
- {
- v[i] -= 10;
- per = 1;
- }
- else
- {
- per = 0;
- }
- }
- if (per == 1)
- {
- v.push_back(1);
- }
- norm(v);
- return v;
- }
- void dec(vector < short >& v, vector < short > v1)
- {
- v.resize(max(v.size(), v1.size()));
- v1.resize(v.size());
- int per = 0;
- for (int i = v.size() - 1; i >= 0; i--)
- {
- if (v[i] - v1[i] - per >= 0)
- {
- v[i] -= v1[i] + per;
- per = 0;
- }
- else
- {
- v[i] -= v1[i] + per;
- v[i] += 10;
- per = 1;
- }
- }
- norm(v);
- }
- vector < short > multiple(vector < short > v, short num)
- {
- vector < short > v2 = { num % 10, num / 10 };
- vector < short > ans(v.size() + 2);
- for (int i = 0; i < v.size(); i++)
- {
- for (int j = 0; j < 2; j++)
- {
- ans[i + j] += v[i] * v2[j];
- }
- }
- int per = 0;
- for (int i = 0; i < ans.size(); i++)
- {
- ans[i] += per;
- per = ans[i] / 10;
- ans[i] %= 10;
- }
- norm(ans);
- return ans;
- }
- int main()
- {
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- ios_base::sync_with_stdio(false);
- short n;
- string s;
- cin >> n >> s;
- vector < Node > p = build(s);
- vector < vector < short > > dp(30050);
- dp[0] = { 0 };
- for (int i = 1; i <= s.size(); i++)
- {
- dp[i] = { 0 };
- dp[i] = multiple(add(dp[i - 1], { 1 }), n);
- dp[i].shrink_to_fit();
- //dp[i] = n * (dp[i - 1] + 1);
- for (char c = 'a'; c <= 'z'; c++)
- {
- if (c != s[i - 1])
- {
- dec(dp[i], dp[p[i - 1].next[c - 'a']]);
- //if (p[dp[p[i - 1]].next[c - 'a']].last == )
- //dp[i] -= dp[p[i - 1].next[c]];
- }
- }
- for (char c = 'a'; c <= 'z'; c++)
- {
- if (c != s[i - 1])
- {
- //dec(dp[i], dp[p[i - 1].next[c - 'a']]);
- if (last[p[i - 1].next[c - 'a']] <= i)
- {
- dp[p[i - 1].next[c - 'a']].clear();
- dp[p[i - 1].next[c - 'a']].shrink_to_fit();
- }
- //dp[i] -= dp[p[i - 1].next[c]];
- }
- }
- dp[i].shrink_to_fit();
- }
- norm(dp[s.size()]);
- reverse(dp[s.size()].begin(), dp[s.size()].end());
- write_vector(dp[s.size()]);
- //cout << dp[s.size()];
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement