K-string HDU - 4641 (后缀自动机)
Posted jiaaaaaaaqi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了K-string HDU - 4641 (后缀自动机)相关的知识,希望对你有一定的参考价值。
K-string
\[ Time Limit: 2000 ms\quad Memory Limit: 131072 kB \]
题意
给出长度为 \(n\) 的字符串,接下来跟着 \(m\) 次操作,每次 \(1\) 操作往字符串末尾加一个 \(char\),\(2\) 操作统计字符串中出现次数 \(\geq K\) 的字符串个数。
思路
统计一个字符串出现个数,可以用 \(dp[father] = \sum dp[u]\),来计算,那么我们可以知道,一个点从本身往根跑的过程,这个 \(dp\) 值是一直在增大的,所以只要跑到某一个地方的 \(dp \geq K\),就可以不往上更新了,这样插入一个字符,更新一次,边更新边统计答案就可以了。(数据比较水,这样暴力在全是 \(a\) 的情况下是会 \(T\) 的)
这题我用结构体数组写 \(sam\) 被卡了,最后换了纯数组的 \(sam\)。\(emmm\)
/***************************************************************
> File Name : a.cpp
> Author : Jiaaaaaaaqi
> Created Time : 2019年06月06日 星期四 00时14分49秒
***************************************************************/
#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lowbit(x) x & (-x)
#define mes(a, b) memset(a, b, sizeof a)
#define fi first
#define se second
#define pii pair<int, int>
typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 5e5 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll INF = 1e18 + 100;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
using namespace std;
int n, m;
int cas, tol, T;
struct Sam
int node[maxn][27], fa[maxn], step[maxn];
int dp[maxn];
int sz, last, K, ans;
int newnode()
mes(node[++sz], 0);
fa[sz] = step[sz] = 0;
dp[sz] = 0;
return sz;
void init()
ans = sz = 0;
last = newnode();
void insert(int k)
int p = last, np = last = newnode();
step[np] = step[p]+1;
for(; p&&!node[p][k]; p=fa[p])
node[p][k] = np;
if(p==0)
fa[np] = 1;
else
int q = node[p][k];
if(step[q] == step[p]+1)
fa[np] = q;
else
int nq = ++sz;
memcpy(node[nq], node[q], sizeof(node[q]));
dp[nq] = dp[q];
fa[nq] = fa[q];
step[nq] = step[p]+1;
fa[np] = fa[q] = nq;
for(; p&&node[p][k]==q; p=fa[p])
node[p][k] = nq;
void update(int p)
for(; p&&dp[p]<K; p=fa[p])
dp[p]++;
if(dp[p]>=K) ans+=step[p]-step[fa[p]];
sam;
char s[50005];
int main()
while(~scanf("%d%d%d", &n, &m, &sam.K))
scanf("%s", s+1);
sam.init();
int len = strlen(s+1);
for(int i=1; i<=len; i++)
sam.insert(s[i]-'a'+1);
sam.update(sam.last);
char ss[5];
while(m--)
int id;
scanf("%d", &id);
if(id == 1)
scanf("%s", ss+1);
sam.insert(ss[1]-'a'+1);
sam.update(sam.last);
else
printf("%d\n", sam.ans);
return 0;
以上是关于K-string HDU - 4641 (后缀自动机)的主要内容,如果未能解决你的问题,请参考以下文章