Manthan, Codefest 16 C
建trie树,刚好字符串是反向的,直接在原图上向前搜索就OK了………………
可怜的我竟然用了RK来hash,在test67那里T了……
贴个RK的
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 | #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <set> #include <vector> #define LL long long using namespace std; const int MAXN = 10050; const int MOD = 1e9 + 7; char tmp[MAXN], str[MAXN]; struct Word{ char s[1005]; int len; }; int n; vector<Word>w; int wmod[MAXN * 10]; int smod[1005]; int ymod[1005]; int dp[MAXN]; int main(){ w.clear(); int len; scanf ( "%d" , &len); scanf ( "%s" , tmp); scanf ( "%d" , &n); ymod[0] = 1; for ( int i = 1; i <= 1000; i++){ ymod[i] = ((LL)ymod[i - 1] * 26) %MOD; } for ( int i = len - 1; i >= 0; i--){ str[len - i] = tmp[i]; } str[len + 1] = '\0' ; int minlen = 0; Word tmps; for ( int i = 0; i < n; i++){ scanf ( "%s" , tmps.s); tmps. len = strlen (tmps.s); w.push_back(tmps); minlen = max(minlen, tmps.len); } //cout << 0 << endl; for ( int i = 0; i < n; i++){ int val = 0; int weight = 1; for ( int j = 0; j < w[i].len; j++){ val = ((LL)val + (LL)(w[i].s[j] >= 'A' && w[i].s[j] <= 'Z' ? (w[i].s[j] - 'A' ) : (w[i].s[j] - 'a' )) * weight % MOD )%MOD; weight = (LL)weight * 26 % MOD; } wmod[i] = val; } /* for(int i = 0; i < n; i++) cout << wmod[i] << endl; */ memset (smod, -1, sizeof (smod)); smod[0] = 0; memset (dp, -1, sizeof (dp)); dp[0] = 0; for ( int i = 1; i <= len; i++){ for ( int k = minlen + 1; k >= 1; k--){ if (smod[k - 1] == -1) continue ; else { smod[k] = ((LL)smod[k- 1] + (LL)ymod[k - 1] *( str[i] - 'a' ))%MOD; } } for (vector<Word>::iterator k = w.begin(); k != w.end(); ++k){ char ss = k->s[k->len - 1]; ss = (ss >= 'A' && ss <= 'Z' )? ss - 'A' + 'a' : ss; if (ss != str[i] ) continue ; else { if (smod[k ->len] != -1 && wmod[k - w.begin()] == smod[k->len] && dp[i - k->len] >= 0){ dp[i] = k - w.begin(); break ; } } } } int i = len; while (i){ printf ( "%s" , w[dp[i]].s); i = i - w[dp[i]].len; if (i) printf ( " " ); } printf ( "\n" ); } |
trie树简便快捷啊……
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 | #include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<cmath> #include<vector> #include<queue> using namespace std; const int maxn = 1E4 + 10; struct T{ int ch[26]; int END; T () { memset (ch,0, sizeof (ch)); END = 0; } }t[1000010]; int cnt,n,m,f[maxn],last[maxn]; char x[maxn],y[1010]; vector < char > v[maxn*10]; void Insert( int o, int pos, int len, int num) { for (; pos < len; pos++) { int to; if (y[pos] >= 'a' ) to = y[pos]- 'a' ; else to = y[pos]- 'A' ; if (!t[o].ch[to]) t[o].ch[to] = ++cnt; o = t[o].ch[to]; } t[o].END = num; } void solve( int pos) { int END = max(1,pos-999); int o = 0; for ( int i = pos; i >= END; i--) { o = t[o].ch[x[i]- 'a' ]; if (!o) break ; if ((f[i-1] || i == 1) && t[o].END) { last[pos] = i; f[pos] = t[o].END; break ; } } } void pri( int pos) { if (last[pos] != 1) pri(last[pos]-1); int len = v[f[pos]].size(); for ( int i = 0; i < len; i++) printf ( "%c" ,v[f[pos]][i]); printf ( " " ); } int main() { #ifdef YZY freopen ( "yzy.txt" , "r" ,stdin); #endif cin >> n; scanf ( "%s" ,1+x); cin >> m; for ( int i = 1; i <= m; i++) { scanf ( "%s" ,&y); int len = strlen (y); Insert(0,0,len,i); for ( int j = 0; j < len; j++) v[i].push_back(y[j]); } for ( int i = 1; i <= n; i++) solve(i); pri(n); return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步