优化思路就是第一篇题解的。
其余的就是裸的AC自动机板子
调的很头疼了,特来求助一下
//2023/5/22
//别着急,先通读一遍题目
//别忘了开long long
//写完先看一遍怎么降复杂度
//要么开全局变量要么给定初值
//想想看,有什么情况需要特判
//看看数组开的够不够大
//std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
struct trietree{
int fall=0;
int child[26]={0};
int cnt=0;
int ans=0;
}trie[MAXN];
int tcnt=0;
int mp[MAXN];
int du[MAXN];
void insert(string &s,int i)
{
int rootid=0;
for (char c:s)
{
int cid=c-'a';
if(trie[rootid].child[cid]==0)
{
trie[rootid].child[cid]=++tcnt;
}
rootid=trie[rootid].child[cid];
}
if(!trie[rootid].cnt) trie[rootid].cnt=i;
mp[i]=trie[rootid].cnt;
}
queue<int> que;
void getfall()
{
int rootid=0;
for (int i=0;i<26;i++)
{
if(trie[rootid].child[i])
{
que.push(trie[rootid].child[i]);
}
}
while(que.size())
{
rootid=que.front();
que.pop();
for (int i=0;i<26;i++)
{
if(trie[rootid].child[i])
{
que.push(trie[rootid].child[i]);
du[trie[rootid].fall]++;
trie[trie[rootid].child[i]].fall=trie[trie[rootid].fall].child[i];
}
else
{
trie[rootid].child[i]=trie[trie[rootid].fall].child[i];
}
}
}
}
int vis[MAXN];
void ACmachine(string &s)
{
int rootid=0;
for (int i=0;i<s.length();i++)
{
int id=s[i]-'a';
rootid=trie[rootid].child[id];
trie[rootid].ans++;
}
}
void topsort()
{
for (int i=0;i<=tcnt;i++)
{
if(du[i]==0)
{
que.push(i);
}
}
while(!que.empty())
{
int rootid=que.front();
que.pop();
vis[trie[rootid].cnt]=trie[rootid].ans;
int v=trie[rootid].fall;
du[v]--;
trie[v].ans+=trie[rootid].ans;
if(du[v]==0) que.push(v);
}
}
int main()
{
int n;
string s;
cin>>n;
for (int i=1;i<=n;i++)
{
cin>>s;
insert(s,i);
}
getfall();
cin>>s;
ACmachine(s);
topsort();
for (int i=1;i<=n;i++)
{
cout<<vis[mp[i]]<<endl;
}
return 0;
}