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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| #include <iostream> #include <vector> #include<string.h> using namespace std;
inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'|| ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;} #define Z(x) (x)*(x) #define pb push_back
#define N 20010 #define M 300010
int n, m, i, j, k, T, T0; int nxt[M][26], fail[M], tot; short dfn[M], len[M], lst[M], p[M]; int rt, u, v, w[N], ans, f; char str[M]; int q[M], l, r; vector<int>G[M];
int mx[N<<3]; void add(int k, int l, int r, int x, int y, int z) { if(l>=x && r<=y) return mx[k]=max(mx[k], z), void(); int m=(l+r)>>1; if(x<=m) add(k<<1, l, m, x, y, z); if(y>=m+1) add(k<<1|1, m+1, r, x, y, z); } int que(int k, int l, int r, int x) { if(l==r) return mx[k]; int m=(l+r)>>1; if(x<=m) return max(mx[k], que(k<<1, l, m, x)); else return max(mx[k], que(k<<1|1, m+1, r, x)); } void clear(int k, int l, int r) { mx[k]=0; if(l==r) return ; int m=(l+r)>>1; clear(k<<1, l, m); clear(k<<1|1, m+1, r); }
void init() { rt=u=v=tot=ans=l=r=0; }
void Trie(int u, int i) { if(!str[i]) return dfn[u]=lst[u]=1, void(); int c=str[i]-'a'; p[u]=1; if(!nxt[u][c]) nxt[u][c]=++tot; Trie(nxt[u][c], i+1); }
void bfs() { memset(fail, 0, sizeof(fail)); q[++r]=1; fail[1]=0; while(l<r) { u=q[++l]; if(!p[u]) continue; for(int i=0; i<26; ++i) if(nxt[u][i]) { v=nxt[u][i]; k=fail[u]; while(k && p[k] && !nxt[k][i]) k=fail[k]; if(p[k] && nxt[k][i]) fail[v]=nxt[k][i]; else fail[v]=1; q[++r]=v; } } }
void dfs(int x) { if(dfn[x]) ++m; dfn[x]=m; for(int y : G[x]) dfs(y); if(lst[x]) lst[x]=m, ++m; else lst[x]=m; }
signed main() {
T=read(); for(T0=1; T0<=T; ++T0) { init(); n=read(); rt=tot=1; for(i=1; i<=n; ++i) { scanf("%s", str+len[i-1]+1); w[i]=read(); len[i]=strlen(str+len[i-1]+1)+len[i-1]; Trie(rt, len[i-1]+1); } bfs(); for(i=2; i<=tot; ++i) G[fail[i]].pb(i); m=1; dfs(1); for(i=1; i<=n; ++i) { f=w[i]; for(j=len[i-1]+1, u=1; j<=len[i]; ++j) { u=nxt[u][str[j]-'a']; f=max(f, que(1, 1, m, dfn[u])+w[i]); } ans=max(ans, f); add(1, 1, m, dfn[u], lst[u], f); } clear(1, 1, m); for(i=1; i<=tot; ++i) { if(p[i]) memset(nxt[i], 0, sizeof(nxt[i])); fail[i]=dfn[i]=lst[i]=p[i]=0; G[i].clear(); } printf("Case #%d: %d\n", T0, ans); }
return 0; }
|