Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #include <iostream>
- #include <map>
- #include <vector>
- #include <string>
- using namespace std;
- struct state {
- int len, lkk;
- map<char, int> next;
- };
- const int mxln = 10000*21;
- state st[mxln * 2];
- int size, last;
- int cnt[2 * mxln];
- vector<int> pos[mxln];
- void sa_init() {
- size = last = 0;
- st[0].len = 0;
- st[0].lkk = -1;
- ++size;
- }
- void sa_extend(char c) {
- int cc = size++;
- st[cc].len = st[last].len + 1;
- pos[st[cc].len].push_back(cc);
- cnt[cc] = 1;
- int k;
- for (k = last; k != -1 && !st[k].next.count(c); k = st[k].lkk)
- st[k].next[c] = cc;
- if (k == -1)
- st[cc].lkk = 0;
- else {
- int q = st[k].next[c];
- if (st[k].len + 1 == st[q].len)
- st[cc].lkk = q;
- else {
- int clone = size++;
- st[clone].len = st[k].len + 1;
- pos[st[clone].len].push_back(clone);
- st[clone].next = st[q].next;
- st[clone].lkk = st[q].lkk;
- for (; k != -1 && st[k].next[c] == q; k = st[k].lkk)
- st[k].next[c] = clone;
- st[q].lkk = st[cc].lkk = clone;
- }
- }
- last = cc;
- }
- int count_substr(string& s)
- {
- int st_index = 0;
- int j = 0;
- while (j < s.length())
- {
- char c = s[j];
- st_index = st[st_index].next[c];
- j++;
- }
- return cnt[st_index];
- }
- int main()
- {
- int n, n1;
- cin >> n1;
- vector<string> ss;
- string s,text;
- for (int i = 0; i < n1; i++)
- {
- cin >> s;
- ss.push_back(s);
- if (text.length() != 0)
- text += "#";
- text += s;
- }
- memset(cnt, 0, sizeof(cnt));
- s = text;
- sa_init();
- for (size_t i = 0; i < s.length(); i++)
- sa_extend(s[i]);
- n = text.length();
- for (int i = n; i > 0; --i)
- for (int j = 0; j < (int)pos[i].size(); ++j)
- {
- int x = pos[i][j];
- if (st[x].lkk >= 0) cnt[st[x].lkk] += cnt[x];
- }
- for (int i = 0; i < n1; i++)
- cout << (count_substr(ss[i]) - 1) << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement