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平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数 ...
随机推荐
- pyhton3 logging模块
1.简单的将日志打印到屏幕 import logging logging.debug('This is debug message')logging.info('This is info mess ...
- BIO,NIO和AIO
BIO:同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善. NIO: ...
- P3825 [NOI2017]游戏
题目 P3825 [NOI2017]游戏 做法 \(x\)地图外的地图好做,模型:\((x,y)\)必须同时选\(x \rightarrow y,y^\prime \rightarrow x^\pri ...
- IDEA: 遇到问题Error during artifact deployment. See server log for details.详解
IDEA 的配置确实有些烦人,完整的配置我之前发过,现在有个著名的报错: Error during artifact deployment. See server log for details. 这 ...
- CCNA 课程 三
交换机的MAC地址学习情况: 1.从一个接口收到数据帧,根据数据帧的原mac地址查找交换机的mac地址表,如果没有找到,将会添加数据帧的原mac地址和收到数据帧接口的对应条目,放进交换机的mac地址表 ...
- freemarker日志实现过程分析
freemarker有自己的log类,这是一个抽象类,具体的日志打印委托给classpath里面合适的日志jar包来执行,寻找合适日志jar的查找顺序是:Apache Log4J, Apache Av ...
- Android 开发人员必须掌握的 10 个开发工具
Android 开发人员必须掌握的 10 个开发工具 Android SDK 本身包含很多帮助开发人员设计.开发.测试和发布 Android 应用的工具,在本文中,我们将讨论 10 个最常用的工具. ...
- 算法总结之 在单链表和双链表中删除倒数第k个节点
分别实现两个函数,一个可以删除单链表中倒数第k个节点,另一个可以删除双链表中倒数第k个节点 思路: 如果链表为空,或者k<1 参数无效 除此之外 让链表从头开始走到尾,每移动一步,就让k的值减1 ...
- 关于Json如何转换成对象及获值问题!
var result = eval('('+result+')'); result为Json 转换成var result对象,可以 if(result.success){ window.locatio ...
- POJ 1015 Jury Compromise(dp坑)
提议:在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑选n个人作为陪审团的候选人,然后再从这n个人中选m人组成陪审团.选m人的办法是:控方和辩方会根据对候选 ...