复杂度n^2 ,没想出来怎么优化,‘*’赋值可以差分写,不过不减复杂度
#include <queue> #include <cstdlib> #include <cmath> #include <cstdio> #include <string> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 2*1e3+9; typedef pair<int,int> pii; int trie[maxn][26]; int cntword[maxn]; int fail[maxn]; int cnt = 0; int len[maxn]; void insertWords(string s){ int root = 0; for(int i=0;i<(int)s.size();i++){ int next = s[i] - 'a'; if(!trie[root][next]) { trie[root][next] = ++cnt; len[cnt]=len[root]+1; } root = trie[root][next]; } cntword[root]++; } void getFail(){ queue <int>q; for(int i=0;i<26;i++){ if(trie[0][i]){ fail[trie[0][i]] = 0; q.push(trie[0][i]); } } while(!q.empty()){ int now = q.front(); q.pop(); for(int i=0;i<26;i++){ if(trie[now][i]){ fail[trie[now][i]] = trie[fail[now]][i]; q.push(trie[now][i]); } else trie[now][i] = trie[fail[now]][i]; } } } std::vector<pii> v; void query(string &s){ int now = 0; for(int i=0;i<(int)s.size();i++){ now = trie[now][s[i]-'a']; for(int j=now;j;j=fail[j]){ if(cntword[j]) { for(int ss=i-len[j]+1;ss<=i;ss++) { s[ss]='*'; } // v.push({i-len[j]+1,i}); break; } } } /*int p[maxn]; int vis[maxn]; memset(p,0,sizeof(p)); memset(vis,0,sizeof(vis)); for(pii x:v) { int } */ } int main() { int n; string s; cin >> n; for(int i=0;i<n;i++){ cin >> s ; insertWords(s); } fail[0] = 0; getFail(); cin >> s ; query(s); cout<<s<<endl; //cout << query(s) << endl; return 0; }