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平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数 ...
随机推荐
- 前端基础之JavaScript_(5)_DOM对象总结
DOM 定义了访问和操作HTML文档的标准方法 访问(查找标签) //---- 直接查找 document.getElementById(“idname”) document.getElementsB ...
- LeetCode:下一个排列【31】
LeetCode:下一个排列[31] 题目描述 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排 ...
- PHP用星号隐藏部份用户名、身份证、IP、手机号、邮箱等实例
一.仿淘宝评论购买记录隐藏部分用户名,以下代码亲测可用. function cut_str($string, $sublen, $start = 0, $code = 'UTF-8') { if( ...
- Go bufio库
bufio.Scanner bufio包使处理输入和输出方便又高效.Scanner类型是该包最有用的特性之一,它读取输入并将其拆成行或单词:通常是处理行形式的输入最简单的方法.该变量从程序的标准输入中 ...
- idea ource 1.5 中不支持 switch 中存在字符串
报错内容如下: Error:(49, 20) java: -source 1.5 中不支持 switch 中存在字符串, (请使用 -source 7 或更高版本以允许 switch 中存在字符串) ...
- 使用eclipse搭建第一个python+Django的web开发实例
python+Django的web开发实例 一.创建一个项目如果这是你第一次使用Django,那么你必须进行一些初始设置.也就是通过自动生成代码来建立一个Django项目--一个Django项目的 ...
- 域名注册中EAP期间是什么意思
所谓域名申请期间的EAP指的是,域名优先注册期,行业上也称为“早期接入期”,这个期间的时间是由该域名所在的管理注册局定,而这个EPA期的时间长度也不一样,有的是一个星期,也有的长达两个星期. 域名EA ...
- NLP-特征选择
文本分类之特征选择 1 研究背景 对于高纬度的分类问题,我们在分类之前一般会进行特征降维,特征降维的技术一般会有特征提取和特征选择.而对于文本分类问题,我们一般使用特征选择方法. 特征提取:PCA.线 ...
- JavaWeb -- Jsp 自定义标签的使用
Jsp中不要有一行Java代码, 需要的Java代码都要封到自定义标签中. 自定义标签的作用: a. 自定义标签除了可以移除jsp页面java代码外,它也可以实现以上功能. b. 控制jsp页面某 ...
- 读写properties文件方法
按key读取properties文件中的value public static String readSystemConfig(String key){ Properties prop = new P ...