HDU3518Boring counting(后缀自动机)
Take aaaa as an example.”a” apears four times,”aa” apears two times without overlaping.however,aaa can’t apear more than one time without overlaping.since we can get “aaa” from [0-2](The position of string begins with 0) and [1-3]. But the interval [0-2] and [1-3] overlaps each other.So “aaa” can not take into account.Therefore,the answer is 2(“a”,and “aa”).
emmmmmmm,WA了,因为L和R错了;
找L和R需要全部字母插入后拓扑排序求出。
如果不,maxlen(v)+1 < maxlen(x)的时候会拆点,导致x点和拆出的y点L,R出错。
。。。好像是个很弱智的问题,勿喷,我知道错啦。
和HDU4416差不多,写法上一个从0开始,一个从1开始。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
const int maxn=;
int tot,slink[*maxn],trans[*maxn][],maxlen[*maxn];
char str[*maxn];
int R[maxn],L[maxn],last;
long long ans;
void init()
{
ans=tot=;
last=;
memset(trans[],-,sizeof(trans[]));
memset(L,,sizeof(L));
memset(R,,sizeof(R));
slink[]=-; maxlen[]=;
}
void add_char(int pos,char chr)
{
bool ww=false;
int c=chr-'a',nq=;
int p=last,np=++tot;
maxlen[np]=maxlen[p]+;
memset(trans[np],-,sizeof(trans[np]));
while(p!=-&&trans[p][c]==-) trans[p][c]=np,p=slink[p];
if(p==-) slink[np]=;
else
{
int q=trans[p][c];
if(maxlen[q]!=maxlen[p]+)
{
nq=++tot;
memcpy(trans[nq],trans[q],sizeof(trans[q]));
maxlen[nq]=maxlen[p]+;
slink[nq]=slink[q];
slink[np]=slink[q]=nq;
while(p!=-&&trans[p][c]==q) trans[p][c]=nq,p=slink[p];
L[nq]=R[nq]=pos;
ww=true;
}
else slink[np]=q;
}
last=np;
for(;np>;np=slink[np]){
if(!L[np]) L[np]=pos;
R[np]=pos;
}
}
int main() {
while(~scanf("%s",str)){
if(str[]=='#') return ;
init();
int N=strlen(str);
for(int i=; i<N; i++) add_char(i+,str[i]);
for(int i=;i<=tot;i++) {
if(R[i]-L[i]>=maxlen[i]) ans+=maxlen[i]-maxlen[slink[i]];
else ans+=max(,R[i]-L[i]-maxlen[slink[i]]+);
}
printf("%lld\n",ans);
}
}
别人的AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lng long long
using namespace std; const int maxn = + ;
char s[maxn];
int str[maxn], len;
struct suffixautomaton
{
int ch[maxn][], pre[maxn], val[maxn], top[maxn];
int c[maxn];
int l[maxn], r[maxn];
int sz, last; void init() { pre[] = -; last = ; sz = ; memset(ch[], , sizeof(ch[])); } void insert(int x)
{
int p = last, np = sz++; last = np;
memset(ch[np], , sizeof(ch[np]));
val[np] = val[p] + ;
while(p != - && ch[p][x] == )
{
ch[p][x] = np;
p = pre[p];
}
if(p == -) pre[np] = ;
else
{
int q = ch[p][x];
if(val[q] == val[p] + )
pre[np] = q;
else
{
int nq = sz++;
memcpy(ch[nq], ch[q], sizeof(ch[q]));
val[nq] = val[p] + ;
pre[nq] = pre[q];
pre[q] = pre[np] = nq;
while(p != - && ch[p][x] == q) { ch[p][x] = nq; p = pre[p]; }
}
}
} void solve()
{
memset(c, , sizeof(c));
for(int i = ; i < sz; ++i) c[val[i]] += ;
for(int i = ; i <= len; ++i) c[i] += c[i - ];
for(int i = ; i < sz; ++i) top[--c[val[i]]] = i;
for(int i = ; i < sz; ++i) { l[i] = len + ; r[i] = -; }
for(int i = ; ; i = ch[i][str[val[i]]])
{
l[i] = r[i] = val[i];
if(val[i] == len) break;
}
for(int i = sz - ; i > ; --i)
{
int u = top[i];
l[pre[u]] = min(l[pre[u]], l[u]);
r[pre[u]] = max(r[pre[u]], r[u]);
}
lng ans = ;
for(int i = ; i < sz; ++i)
{
if(r[i] - l[i] > val[pre[i]])
{
lng tmp = min(val[i], r[i] - l[i]);
ans += (tmp - val[pre[i]]);
}
}
printf("%I64d\n", ans);
}
}sam; int main()
{
while(~scanf("%s", s) && s[] != '#')
{
len = strlen(s);
sam.init();
for(int i = ; s[i]; ++i)
{
str[i] = s[i] - 'a';
sam.insert(str[i]);
}
sam.solve();
}
return ;
}
地址:http://blog.csdn.net/cool_Fires/article/details/9732475
HDU3518Boring counting(后缀自动机)的更多相关文章
- Boring counting HDU - 3518 后缀自动机
题意: 对于给出的字符串S, 长度不超过1000, 求其中本质不同的子串的数量, 这些子串满足在字符串S中出现了至少不重合的2次 题解: 将串放入后缀自动机中然后求出每一个节点对应的子串为后缀的子串出 ...
- HDU 5343 MZL's Circle Zhou 后缀自动机+DP
MZL's Circle Zhou Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- BZOJ 后缀自动机四·重复旋律7
后缀自动机四·重复旋律7 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 神奇的 ...
- 【Codeforces235C】Cyclical Quest 后缀自动机
C. Cyclical Quest time limit per test:3 seconds memory limit per test:512 megabytes input:standard i ...
- 【hihocoder#1413】Rikka with String 后缀自动机 + 差分
搞了一上午+接近一下午这个题,然后被屠了个稀烂,默默仰慕一晚上学会SAM的以及半天4道SAM的hxy大爷. 题目链接:http://hihocoder.com/problemset/problem/1 ...
- 【BZOJ-3998】弦论 后缀自动机
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2018 Solved: 662[Submit][Status] ...
- HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)
Reincarnation Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)To ...
- hihoCoder 后缀自动机三·重复旋律6
后缀自动机三·重复旋律6 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数列. 现在小Hi ...
- hihoCoder #1445 : 后缀自动机二·重复旋律5
#1445 : 后缀自动机二·重复旋律5 时间限制:10000ms 单点时限:2000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数 ...
随机推荐
- requirejs源码分析: config中shim
shim处理的源码: //Merge shim if (cfg.shim) { eachProp(cfg.shim, funct ...
- Springboot文件下载
https://blog.csdn.net/stubbornness1219/article/details/72356632 Springboot对资源的描述提供了相应的接口,其主要实现类有Clas ...
- Java系列之EJB 理解
EJB = Enterprise Java Bean,它和JavaBean有本质的区别,最好不要将他们混淆起来,就像不要将Java和 Javascript混淆起来一样.EJB有3中类型:Session ...
- Shell 条件判断总结
-b file 若文件存在且是一个块特殊文件,则为真 -c file 若文件存在且是一个字符特殊文件,则为真 -d file 若文件存在且是一个目录,则为真 -e file 若文件存在,则为真 -f ...
- GPU的工作原理
转:https://blog.csdn.net/p23onzq/article/details/79609629 在GPU出现以前,显卡和CPU的关系有点像“主仆”,简单地说这时的显卡就是画笔,根据各 ...
- jq中ajax的dataType:"json"是指什么?
dataType String 预期服务器返回的数据类型.如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断,比如XML MIME类型就被识别为XML.在1.4中,JSON就 ...
- Qt下TCP编程
一.服务器 1.声明一个QTcpServer对象 QTcpServer* serverListener; 2.new出对象 this->serverListener = new QTcpServ ...
- linux下常用FTP命令 1. 连接ftp服务器[转]
1. 连接ftp服务器 格式:ftp [hostname| ip-address]a)在linux命令行下输入: ftp 192.168.1.1 b)服务器询问你用户名和密码,分别输入用户名和相应密码 ...
- 如何在java代码中调用一个web项目jsp或者servlet
有时候需要调用一个web项目的jsp或者servlet,但是执行内部的代码,并不是打开jsp,例如需要在一段java代码中清除一个web项目中的缓存,那么可以把清除缓存的代码放在该web项目的一个se ...
- js,java,ajax实现跨域访问及其原理
http://blog.csdn.net/saytime/article/details/51540876 这篇文章对跨域访问做了较为细致得分析,我这里做下简单总结 1.实现跨域访问原理: 浏览器由于 ...