SP8093 JZPGYZ - Sevenk Love Oimaster
2024-10-18 06:51:36
广义后缀自动机……
其实也不是很难理解,就是每次SAM插入一个串之后,插入新的串的时候,要把last重新调到1的位置,共用一些节点。
这个题我们首先要预处理出来每个状态被多少个串共用。挺暴力的就是每次把节点染色,如果节点没被染色就给他染一下,然后记录当前节点又被共用了一次。
最后跑的时候和匹配是一样的,每次输出末尾节点共用次数即可。
#include<bits/stdc++.h>
#define rep(i,a,n) for(register int i = a;i <= n;i++)
#define per(i,n,a) for(register int i = n;i >= a;i--)
#define enter putchar('\n')
#define pr pair<int,int>
#define mp make_pair
#define fi first
#define sc second
using namespace std;
typedef long long ll;
const int M = 100005;
const int N = 10000005;
const int INF = 2147483647;
int read()
{
int ans = 0,op = 1;
char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
while(ch >='0' && ch <= '9') ans = ans * 10 + ch - '0',ch = getchar();
return ans * op;
}
string s[M],t;
int n,m,k,times[M<<1],col[M<<1];
struct Suffix
{
int last,cnt,ch[M<<1][26],fa[M<<1],l[M<<1];
void extend(int c)
{
int p = last,np = ++cnt;
last = cnt,l[np] = l[p] + 1;
while(p && !ch[p][c]) ch[p][c] = np,p = fa[p];
if(!p) {fa[np] = 1;return;}
int q = ch[p][c];
if(l[q] == l[p] + 1) fa[np] = q;
else
{
int nq = ++cnt;
l[nq] = l[p] + 1,memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq] = fa[q],fa[q] = fa[np] = nq;
while(ch[p][c] == q) ch[p][c] = nq,p = fa[p];
}
}
void cal(string b,int q)
{
int cur = 1,h = b.length();
rep(j,0,h-1)
{
cur = ch[cur][b[j] - 'a'];
int t = cur;
while(t && col[t] != q) times[t]++,col[t] = q,t = fa[t];
}
}
void match(string b)
{
int cur = 1;
rep(i,0,k-1) cur = ch[cur][b[i]-'a'];
printf("%d\n",times[cur]);
}
}SAM;
int main()
{
n = read(),m = read();
SAM.cnt = 1;
rep(i,1,n)
{
cin >> s[i],k = s[i].length();
SAM.last = 1;
rep(j,0,k-1) SAM.extend(s[i][j] - 'a');
}
rep(i,1,n) SAM.cal(s[i],i);
while(m--) cin >> t,k = t.length(),SAM.match(t);
return 0;
}
最新文章
- 《Entity Framework 6 Recipes》中文翻译系列 (22) -----第五章 加载实体和导航属性之延迟加载
- iwebshop二次开发
- easy ui datagrid 设置冻结列
- android添加edittext后布局就不好用
- uva 10129 poj 1386 hdu 1116 zoj 2016 play on words
- Linux系统服务 1 ---- rSyslog日志服务
- [LeetCode] Trapping Rain Water II 题解
- [学习OpenCV攻略][003[初试牛刀——显示图片]
- 如何用Math.max.apply()获取数组最大/小值
- 使用Ant Build时提示错误: 编码GBK的不可映射字符
- Jenkins+Git+Gitlab+Ansible实现持续集成自动化部署动态网站(二)--技术流ken
- jq demo--横向+展开菜单,支持m站
- python的type class
- Qt: 加入打印支持
- InfluxDB Java入门
- 4196. [NOI2015]软件包管理器【树链剖分】
- CentOS的update-grub2命令
- mysql负载均衡完美解决方案
- POJ 3752 字母旋转游戏
- OpenGL进阶(十四) - UVN Camera实现
热门文章
- [剑指Offer]2.变态跳台阶
- 和菜鸟们一起攻克金盾2018SS加密视频
- 第七讲_图像描述(图说)Image Captioning
- android wifi state and wifi ap state
- Android的logger机制分析
- java web 站点头像上传处理 (springmvc +bootstrap+cropper)
- GB28181对接视频流
- 对OpenCV中Haar特征CvHaarClassifierCascade等结构理解
- HTML5开发移动web应用—JQuery Mobile(1)
- 关于global和$GLOBALS[]的一道经典面试题