Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <iomanip>
- #include <algorithm>
- #include <cmath>
- #include <cstring>
- #include <cstdio>
- #include <ctime>
- #include <set>
- using namespace std;
- #define ll long long
- #define ld long double
- const int N = (int)5e5 + 40;
- const int INF = 1e9 + 7;
- const ld EPS = 1e-7;
- const int LOG = 50;
- struct node{
- node *to[30], *link;
- ll an;
- int len;
- };
- void cpy(node * a, node * b){
- a->link = b->link;
- a->an = 0;
- for (int i = 0; i < 27; i++)
- a->to[i] = b->to[i];
- }
- node tree[N], d[5];
- char s[N];
- int msiz;
- node *add(node *last, int x){
- node * cur = tree + msiz++;
- cur->len = last->len + 1, cur->an = 0, cur->link = tree;
- for (int i = 0; i < 27; i++)
- cur->to[i] = NULL;
- node * v = last;
- while (1){
- if (v->to[x] == NULL){
- v->to[x] = cur;
- cur->an += v->an; //
- }
- else{
- node *q = v->to[x];
- if (v->len + 1 == q->len){
- cur->link = q;
- return cur;
- }
- node *clone = tree + msiz++;
- cpy(clone, q);
- clone->len = v->len + 1;
- cur->link = clone;
- q->link = clone;
- while (1){
- if (v->to[x] == q){
- q->an -= v->an; //
- clone->an += v->an;
- v->to[x] = clone;
- }
- else{
- break;
- }
- if (v->link == NULL)
- break;
- v = v->link;
- }
- return cur;
- }
- if (v->link == NULL){
- cur->link = tree;
- return cur;
- }
- v = v->link;
- }
- return cur;
- }
- int main()
- {
- freopen("keepcounted.in", "r", stdin);
- freopen("keepcounted.out", "w", stdout);
- gets(s);
- ll ans = 0;
- int n = strlen(s);
- node *last = tree + msiz++;
- last->len = 0, last->link = NULL, last->an = 1;
- for (int i = 0; i < 27; i++)
- last->to[i] = NULL;
- for (int i = 0; i < n; i++){
- last = add(last, (int)(s[i] - 'a'));
- ans += last->an;
- cout << ans << endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement