#include #include #include #include #include using namespace std; const int MAXN = 1e6+42; map to[MAXN]; int link[MAXN], que[MAXN]; int sz = 1; int max_l[MAXN]; void add_str(string const& s) { int v = 0; for(auto c : s) { if(!to[v][c]) to[v][c] = sz++; v = to[v][c]; } max_l[v] = max((int)max_l[v], (int)s.size()); } void push_links() { link[0] = -1; int st = 0, fi = 1; que[0] = 0; while(st < fi) { int v= que[st++]; //cerr << v <<" " << link[v] << endl; if(link[v] != -1) max_l[v] = max(max_l[v], max_l[link[v]]); for(auto it : to[v]) { int u = it.second; int c = it.first; int j = link[v]; while(j!=-1 && !to[j][c]) j = link[j]; if(j!=-1) link[u] = to[j][c]; else link[u] = 0; que[fi++] = u; } } //cerr << "A " << fi << endl; } int32_t main(){ ios_base::sync_with_stdio(0); cin.tie(0); int n; cin >> n; string s; cin >> s; //assert(n == s.size()); for(int i=0; i> tmp; add_str(tmp); } push_links(); //for(int i=0; i > > edges; edges.resize(M+1); int j=0; for (int i=0; i < M; i ++) { while (j != -1 && !to[j][s[i]]) j = link[j]; if (j==-1) j=0; else j=to[j][s[i]]; edges[i+1].push_back(make_pair(i, 0)); //cout << "max_l " << j << " " << max_l[j] << endl; if (max_l[j] == 0) continue; int start = i - max_l[j] + 1; edges[start].push_back(make_pair(i+1, 1)); //cout << "add edge " << start << " " << i +1 << endl; } vector dist; dist.resize(M+1, -1); priority_queue > que; que.push(make_pair(0, 0)); dist[0]=0; while (que.size() > 0) { auto node1 = que.top(); que.pop(); int node = node1.second; //cout << "node " << node << endl; if (dist[node] != -node1.first) continue; for (auto ed : edges[node]) { int child = ed.first; int cost = ed.second; int newcost = cost + dist[node]; if (dist[child]==-1 || newcost < dist[child]) { dist[child]=newcost; que.push(make_pair(-newcost, child)); } } } cout << dist[M] << endl; }