1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| #include<iostream> #include<cstdio> #include<cstring> #include<string> using namespace std;
const int CN = 2e5 + 5;
int n, prv[CN]; long long p, q, f[CN]; char s[CN];
class SAM{ public: int nxt[CN << 1], son[CN << 1][26], len[CN << 1], sz, lst, cur, l; void init(int n){ for(int i = 0;i < (n << 1);i++) for(int j = 0;j < 26;j++) son[i][j] = 0; sz = 1, lst = cur = l = len[0] = 0, nxt[0] = -1; } void et(int c){ int u = sz++, p = lst; lst = u, len[u] = len[p] + 1; while(p != -1 && !son[p][c]) son[p][c] = u, p = nxt[p]; if(p == -1) return (void)(nxt[u] = 0); int d = son[p][c]; if(len[d] == len[p] + 1) return (void)(nxt[u] = d); int v = sz++; if(d == cur) cur = v; len[v] = len[p] + 1, nxt[v] = nxt[d], nxt[d] = nxt[u] = v; for(int i = 0; i < 26; i++) son[v][i] = son[d][i]; while(p != -1 && son[p][c] == d) son[p][c] = v, p = nxt[p]; } void del() {if(nxt[cur] != -1 && --l == len[ nxt[cur] ]) cur = nxt[cur];} bool rd(int c) {return son[cur][c] ? cur = son[cur][c], l++, true : false;} }D;
int main() { freopen("_in.in", "r", stdin);
while(cin >> (s + 1)){ n = strlen(s + 1), scanf("%lld%lld", &p, &q), D.init(n);
int l = 1; D.et(s[1] - 'a'), prv[1] = 0; for(int i = 2; i <= n; i++){ bool flag = true; while(!D.rd(s[i] - 'a')){ if(l + 1 == i) {flag = false; break;} D.del(), D.et(s[++l] - 'a'); } prv[i] = flag ? l : 0; if(!flag) D.et(s[++l] - 'a'); }
f[1] = p; for(int i = 2;i <= n;i++) if(prv[i]) f[i] = min(f[i - 1] + p, f[ prv[i] ] + q); else f[i] = f[i - 1] + p;
printf("%lld", f[n]), puts(""); } }
|