标签:trie YBTOJ ll POI2000 while && P2444 失配 getchar
链接:
题目大意:
构造一个无限长的文本串,使得此串不能被匹配。
正文:
好题。我的一开始的思路是,像 01trie 求最大异或那样跑 trie,然后跳失配指针判断合法。但显然假了。
于是得深度思考题意,“不能被匹配”说明跑 trie 时尽量失配,那么在求出失配指针后被修改的 trie 可以往失配方向走。那么只要在 trie 上 DFS 找出一个没有终止标识的环就好了。
代码:
const int N = 3e4 + 10;
inline ll Read()
{
ll x = 0, f = 1;
char c = getchar();
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') f = -f, c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
return x * f;
}
int n;
namespace AC
{
int tot;
int t[N][2], g[N][2], fail[N];
bool vis[N], ins[N], f[N];
void Insert(char *s)
{
int p = 0, len = strlen(s);
for (int i = 0; i < len; i++)
{
int ch = s[i] - '0';
if (!t[p][ch]) g[p][ch] = t[p][ch] = ++tot;
p = t[p][ch];
}
f[p] = 1;
}
queue <int> q;
void Build()
{
while (!q.empty()) q.pop();
for (int i = 0; i <= 1; i++)
if (t[0][i]) q.push(t[0][i]);
while (!q.empty())
{
int u = q.front(); q.pop();
for (int i = 0; i <= 1; i++)
if(t[u][i])
fail[t[u][i]] = t[fail[u]][i],
f[t[u][i]] |= f[t[fail[u]][i]],
q.push(t[u][i]);
else
t[u][i] = t[fail[u]][i];
}
}
bool ans;
void DFS(int u)
{
if (ins[u]) {ans = 1; return;}
if(vis[u] || f[u]) return;
ins[u] = vis[u] = 1;
DFS(t[u][0]), DFS(t[u][1]);
ins[u] = 0;
}
}
char s[N];
int main()
{
n = Read();
for (int i = 1; i <= n; i++)
scanf ("%s", s), AC::Insert(s);
AC::Build();
AC::DFS(0);
puts (AC::ans? "TAK": "NIE");
return 0;
}
标签:trie,YBTOJ,ll,POI2000,while,&&,P2444,失配,getchar 来源: https://www.cnblogs.com/GJY-JURUO/p/14846285.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。