题目大意:

就是对于给定的串S, 长度不超过10000, 求出其有多少种子串T, 使得T在S中至少不重叠地出现了2次以上

大致思路:

很明显的后缀自动机吧, 建立S的后缀自动机, 记录每个节点对应的串出现的最左和最右位置, 以及出现次数, dfs遍历一遍后缀自动机上的点即可了

细节见代码吧

代码如下:

Result  :  Accepted     Memory  :  7076 KB     Time  :  8 ms

/** Author: Gatevin* Created Time:  2015/5/20 20:29:44* File Name: Rin_Tohsaka.cpp*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;
#define foreach(e, x) for(__typeof(x.begin()) e = x.begin(); e != x.end(); ++e)
#define SHOW_MEMORY(x) cout<<sizeof(x)/(1024*1024.)<<"MB"<<endl#define maxn 20010
#define maxm 10010struct Suffix_Automation
{struct State{State *par;State *go[26];int right, val, leftmost, rightmost, mi;bool vis;void init(int _val = 0){par = 0, leftmost = 1e9 + 7, rightmost = -1, val = _val, right = 0, mi = 0;vis = 0;memset(go, 0, sizeof(go));}};State *root, *last, *cur;State nodePool[maxn];void init(){cur = nodePool;root = newState();last = root;}State* newState(int val = 0){cur->init(val);return cur++;}void extend(int w, int pos){State *p = last;State *np = newState(p->val + 1);np->right = 1;np->leftmost = pos, np->rightmost = pos;while(p && p->go[w] == 0){p->go[w] = np;p = p->par;}if(p == 0){np->par = root;}else{State *q = p->go[w];if(p->val + 1 == q->val){np->par = q;}else{State *nq = newState(p->val + 1);memcpy(nq->go, q->go, sizeof(q->go));nq->par = q->par;q->par = nq;np->par = nq;while(p && p->go[w] == q){p->go[w] = nq;p = p->par;}}}last = np;}State* b[maxn];int d[maxm];void topo(){int cnt = cur - nodePool;int maxVal = 0;memset(d, 0, sizeof(d));for(int i = 1; i < cnt; i++)maxVal = max(maxVal, nodePool[i].val), d[nodePool[i].val]++;for(int i = 1; i <= maxVal; i++) d[i] += d[i - 1];for(int i = 1; i < cnt; i++) b[d[nodePool[i].val]--] = &nodePool[i];b[0] = root;}void info(){int cnt = cur - nodePool;State *p;for(int i = cnt - 1; i > 0; i--){p = b[i];p->par->right += p->right;p->mi = p->par->val + 1;p->par->leftmost = min(p->par->leftmost, p->leftmost);p->par->rightmost = max(p->par->rightmost, p->rightmost);}}int ans;void dfs(State *now){now->vis = 1;if(now->right >= 2 && now != root){int len2 = now->rightmost - now->leftmost;if(now->val <= len2) ans += now->val - now->mi + 1;else if(now->mi <= len2) ans += len2 - now->mi + 1;}for(int i = 0; i < 26; i++)if(now->go[i] && !now->go[i]->vis)dfs(now->go[i]);return; }void solve(){ans = 0;dfs(root);printf("%d\n", ans);}
};Suffix_Automation sam;
char in[10010];int main()
{while(scanf("%s", in) != EOF){int len = strlen(in);sam.init();for(int i = 0; i < len; i++)sam.extend(in[i] - 'a', i);sam.topo();sam.info();sam.solve();}return 0;
}

ACdream 1430 SETI 后缀自动机相关推荐

  1. 【POJ1509】Glass Beads 【后缀自动机】

    题意 给出一个字符串,求它的最小表示法. 分析 这个题当然可以用最小表示法做啦!但是我是为了学后缀自动机鸭! 我们把这个字符串长度乘二,然后建SAM,然后在SAM上每次跑最小的那个字母,找出长度为n的 ...

  2. bzoj 2946 [Poi2000]公共串——后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2946 对每个串都建一个后缀自动机,然后 dfs 其中一个自动机,记录同步的话在别的自动机上走 ...

  3. 后缀自动机 ---- P3804 【模板】后缀自动机(求每个等价类最长串的出现次数)

    后缀自动机一些关键点 首先后缀自动机上面每个节点都是一个等价类并且是最长的字符串的结尾 后缀自动机上的fail链反建就是parent tree,下面是SAM和Parent tree的构造 对于这道模板 ...

  4. 洛谷P3966 [TJOI2013]单词(后缀自动机)

    传送门 统计单词出现次数--为啥大家都是写AC自动机的嘞--明明后缀自动机也能做的说-- 统计出现次数这个就直接按长度排序然后做个dp就好,这是SAM的板子的要求啊,不提了 然后考虑怎么让所有串之间隔 ...

  5. hihocoder 后缀自动机专题

    一.后缀自动机基本概念的理解 1.首先后缀自动机的状态是由子串的endpos来决定的 子串的endpos是指一个子串可以在原字符串的哪些位置进行匹配, endpos构成的不同集合划分成不同的状态 关于 ...

  6. BZOJ3998: [TJOI2015]弦论(后缀自动机,Parent树)

    Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...

  7. 从零开始の后缀自动机

    后缀自动机,一个处理字符串问题的神器.听起来很神圣,貌似很难写.其实代码实现并不复杂,萌新估计都能学会. 以前听学长们讲过好多次也看过陈立杰的课件,都不是很明白.今天终于弄明白了,就写一个让大家都能看 ...

  8. 【BZOJ3926】[Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机

    [BZOJ3926][Zjoi2015]诸神眷顾的幻想乡 Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝 ...

  9. 【洛谷 P3975】 [TJOI2015]弦论(后缀自动机)

    题目链接 建出后缀自动机. T=0,每个子串算一次,否则每个子串算该子串的\(endpos\)集合大小次. 用\(f[i]\)表示结点\(i\)表示的\(endpos\)集合大小,则\(f[i]\)为 ...

  10. BZOJ3277 串 【广义后缀自动机】

    Description 字符串是oi界常考的问题.现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中 至少k个字符串的子串(注意包括本身). Input 第一行两个整数n, ...

最新文章

  1. 单片机值得学吗?会单片机能找什么工作?
  2. C#中组件与控件的主要区别是什么?
  3. spring入门-设值方法的差异
  4. C++ STL : 模拟实现STL中的list类
  5. MVC系列——MVC源码学习:打造自己的MVC框架(一:核心原理)(转)
  6. 有向图的十字链表存储
  7. 留存: struts2+jquery+json集成
  8. 18. 树的子结构(C++版本)
  9. Mac安装port(port:command not found解决办法)
  10. 华尔街追逐中国机遇,阿里巴巴收盘价创下历史新高
  11. 慕课java工程师2020版_中国大学慕课2020Java程序设计答案大全
  12. Direct Rendering Manager (DRM)
  13. wireshark抓包分析IP数据报
  14. 命令行查询某web服务器的ip地址
  15. python xlrdxlwt应用 以文本形式存储数字 数字前补零
  16. NAT基本原理与私有IP
  17. BAT疯狂抢人, AI应届博士生年薪201万, 网友: 转行来得及吗???
  18. 解除百度网盘下载限速
  19. Redis缓存对象相关
  20. WinForm轻松实现自定义分页 (转载)

热门文章

  1. 【手游脚本】触动精灵制作脚本
  2. 天啦噜!逾期未还三年,欠款3万变成34万
  3. 创业工场麦刚:不要把创业美化
  4. 论文阅读笔记《Deep Graph Matching under Quadratic Constraint》
  5. c语言程序设计问号是什么意思,在C语言中,该语句在z=xy?x:y中是什么意思,问号表示什么意思...
  6. ES文件浏览器(清理垃圾神器, 强大网盘管理功能, 强大文件分析能力)
  7. 他一生仅凭252个字,就傲视千古…
  8. 手机端html5自动调用touch事件,移动端中touch事件的详解
  9. 姿态估计1-07:FSA-Net(头部姿态估算)-源码无死角讲解(2)-网络框架整体结构分析
  10. 那些年常见的前端bug (持续更新)