p3966单词
后缀自动机版本:
所有的串用(char)('z'+1)连起来,然后建自动机。再用原串在自动机上跑。跑到的位置的endpos就是出现的次数。不过内存有点大。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#define mkp make_pair
using namespace std;
const double EPS=1e-;
typedef long long lon;
const lon SZ=,SSZ=*SZ,APB=,one=,INF=0x7FFFFFFF,mod=;
int n,len,cnt,slink[SSZ],nex[SSZ][APB],maxlen[SSZ];
int minlen[SSZ],endpos[SSZ],in[SSZ];
char ch[SZ];
string str[SZ];
bool green[SSZ]; void add(string &x)
{
for(int i=;i<x.size();++i)
{
ch[++len]=x[i];
}
ch[++len]='z'+;
} int ins(int pre,int c)
{
int z=++cnt,u=pre;
green[z]=;
for(;u!=-&&!nex[u][c];u=slink[u])nex[u][c]=z;
maxlen[z]=maxlen[pre]+;
if(u==-)
{
slink[z]=;
}
else
{
int x=nex[u][c];
if(maxlen[x]==maxlen[u]+)
{
slink[z]=x;
}
else
{
int v=++cnt;
memcpy(nex[v],nex[x],sizeof(nex[x]));
maxlen[v]=maxlen[u]+;
slink[v]=slink[x];
minlen[v]=maxlen[slink[v]]+;
slink[x]=slink[z]=v;
minlen[x]=maxlen[v]+;
for(;u!=-&&nex[u][c]==x;u=slink[u])
nex[u][c]=v;
}
}
minlen[z]=maxlen[slink[z]]+;
return z;
} void topo()
{
for(int i=;i<=cnt;++i)
{
++in[slink[i]];
}
stack<int> stk;
for(int i=;i<=cnt;++i)
{
if(!in[i])stk.push(i),endpos[i]=;
}
for(;stk.size();)
{
int top=stk.top();
stk.pop();
int pre=slink[top];
endpos[pre]+=endpos[top],--in[pre];
if(!in[pre]&&pre)
{
if(green[pre])++endpos[pre];
stk.push(pre);
}
}
} void init()
{
cin>>n;
for(int i=;i<=n;++i)
{
cin>>str[i];
add(str[i]);
}
int pre=;
slink[]=-;
for(int i=;i<=len;++i)
{
pre=ins(pre,ch[i]-'a');
}
topo();
} int calc(string &x)
{
int cur=;
for(int i=;i<x.size();++i)
{
int c=x[i]-'a';
cur=nex[cur][c];
}
return endpos[cur];
} void work()
{
for(int i=;i<=n;++i)
{
cout<<calc(str[i])<<endl;
}
} int main()
{
std::ios::sync_with_stdio();
//freopen("d:\\1.txt","r",stdin);
int casenum;
//cin>>casenum;
//cout<<casenum<<endl;
//for(int time=1;time<=casenum;++time)
//for(int time=1;cin>>n>>qnum,n;++time)
{
//cout<<"Case "<<time<<": ";
init();
work();
}
return ;
}
p3966单词的更多相关文章
- 洛谷 - P3966 - 单词 - AC自动机
https://www.luogu.org/problemnew/show/P3966 因为文本串就是字典本身,所以这个和平时的AC自动机不太一样.平时的query要沿着fail树把子树的出现次数依次 ...
- 洛谷P3966 单词 [TJOI2013] AC自动机
正解:AC自动机 解题报告: 传送门! 先来提供一个40pts错解QAQ 首先看到这题就会想到AC自动机板子题2鸭!然后就照着那题的套路打一下,随便改一点儿,简单来说就是每次经过一个节点都要++,然后 ...
- P3966 [TJOI2013]单词
P3966 [TJOI2013]单词 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出 ...
- 洛谷P3966 [TJOI2013]单词(fail树性质)
P3966 [TJOI2013]单词 题目链接:https://www.luogu.org/problemnew/show/P3966 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单 ...
- 洛谷P3966 [TJOI2013]单词(AC自动机)
题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出格式 输入格式: 第一行一个整数N,表 ...
- 洛谷P3966 [TJOI2013]单词(后缀自动机)
传送门 统计单词出现次数……为啥大家都是写AC自动机的嘞……明明后缀自动机也能做的说…… 统计出现次数这个就直接按长度排序然后做个dp就好,这是SAM的板子的要求啊,不提了 然后考虑怎么让所有串之间隔 ...
- 【洛谷 P3966】 [TJOI2013]单词(AC自动机,差分)
把单词连起来,中间插入间隔符,同 #include <cstdio> #include <queue> #include <cstring> using names ...
- Luogu P3966 [TJOI2013]单词
题目链接 \(Click\) \(Here\) 本题\(AC\)自动机写法的正解之一是\(Fail\)树上跑\(DP\). \(AC\)自动机是\(Trie\)树和\(Fail\)树共存的结构,前者可 ...
- [洛谷P3966][TJOI2013]单词
题目大意:有$n$个字符串,求每个字符串在所有字符串中出现的次数 题解:$AC$自动机,每个节点被经过时$sz$加一,每一个字符串出现次数为其$fail$树子树$sz$和 卡点:$AC$自动机根节点为 ...
随机推荐
- #WEB安全基础 : HTTP协议 | 0x9 GET和POST请求以及请求URI的方式
请求URI的方式 1.URI为完整的请求URI GET http://hackr.jp/index.htm HTTP/1.1 2.在首部字段Host中写明域名或IP地址 GET/index.htm H ...
- 【原创】canvas裁剪上传图片异步提交
<!DOCTYPE html> canvas裁剪图片,纯前端 裁剪文件 后台返回获取裁剪后的文件
- windows10误删Administrator用户的家目录之后
今天在玩Windows10的用户管理的时候,把Administrator用户给开启了,然后还用这个用户登录了系统. 结果就是,第一次登录的时候,闪过一条条初始化配置欢迎信息,Windows系统为Adm ...
- git之commit
面解释的话, 1.git commit -m用于提交暂存区的文件: 2.git commit -am用于提交跟踪过的文件. 要理解它们的区别,首先要明白git的文件状态变化周期,如下图所示 工作目录下 ...
- Scala字节数组转换为数字
1. 2个字节数组转换为整数 def bytes2uint8(_bytes: Array[Byte], _offset: Int): Int = { val b0 = _bytes(_offset) ...
- -bash: belts.awk: command not found
执行awk命令时,没有问题.可是执行awk脚本时,出现这个问题:-bash: belts.awk: command not found. 既然之前直接执行awk命令没有问题,说明awk已经装了,本身是 ...
- String<-->int
String s = "123); int a = Integer.parseInt(s); String b = String.valueOf(a); Integer i = 100; 自 ...
- mtd-utils交叉编译安装
一.获取源码并解压 存储于/home/zhangyi/work/psoc_ltp/tools-ltp-ddt中,解压后的源码存于上一层目录. 1.mtd-utils-2.0.0 wget ftp:// ...
- minSdkVersion
10 It is indeed possible to increase minSdkVersion, but it took me way too much time to find it ou ...
- Prometheus监控学习笔记之Prometheus的Relabel,SD以及Federation功能
0x00 k8s 的监控设计 k8s 默认以及推荐的监控体系是它自己的一套东西:Heapster + cAdvisor + Influxdb + Grafana,具体可以看 这里 . 包括 k8s 自 ...