HDU 4622 Reincarnation(SAM 后缀自动机 求子串的不同子串个数)
来源:互联网 发布:win7网络图标有个红叉 编辑:程序博客网 时间:2024/05/24 00:10
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622
这个题目开始是用后缀数组来做的,但是这个题目对后缀数组时间卡的很紧,后来看解题报告说是用后缀自动机搞定的,想想也是CLJ出题怎么会没有后缀
自动机呢
其实这个题目字符串长度不算长2000,但是查询可以达到10000次,如果每次查询都重新建立后缀自动机来计算不同子串的个数的话会超时,但是考虑到后
缀自动机的构造过程的一个在线的,所以我们就考虑能不能先把要查询的区间排序,然后按照左边界排序,左边界相同的按照右边界从小到达排序,这样,
在构造后缀自动机的时候现在的就可以在先前的基础上构造了(一定是后一个的l和前一个的l相等,如果不相等就重新构造),这样我们最多构造两千次
这样复杂度就够了!
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define maxn 2100struct point{ point *father,*next[26]; int val;}po[maxn*3],*root,*tail;int tot,len,ans[110000];char str[maxn];struct query{ int l,r; int num;}rec[11000];void add(int c,int l){ point *p=tail,*np=&po[tot++]; np->val=l; while(p&&p->next[c]==NULL) p->next[c]=np,p=p->father; if(p==NULL) np->father=root; else { point *q=p->next[c]; if(p->val+1==q->val) np->father=q; else { point *nq=&po[tot++]; *nq=*q; nq->val=p->val+1; np->father=q->father=nq; while(p&&p->next[c]==q) p->next[c]=nq,p=p->father; } } tail=np;}bool cmp(const query &a,const query &b){ if(a.l != b.l) return a.l < b.l; if(a.r !=b.r) return a.r < b.r; return a.num < b.num;}int start(){ memset(po,0,sizeof(po)); len=1,tot=1; root=tail=&po[0]; return 0;}int find_ans()//后缀自动机求不同子串个数{ int i,j,ans=0; for(i=tot-1;i>0;i--) ans+=po[i].val-po[i].father->val; return ans;}int main(){ int t,i,j,k,n; scanf("%d",&t); while(t--) { scanf("%s",str+1); scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d%d",&rec[i].l,&rec[i].r); rec[i].num=i; } sort(rec+1,rec+1+n,cmp); start(); j=1; for(i=1;i<=n;i++) { if(i==1 || rec[i].l==rec[i-1].l) { for(j;j<=rec[i].r;j++) add(str[j]-'a',len++); } else { start(); for(j=rec[i].l;j<=rec[i].r;j++) add(str[j]-'a',len++); } ans[rec[i].num]=find_ans(); } for(i=1;i<=n;i++) printf("%d\n",ans[i]); } return 0;}
- HDU 4622 Reincarnation(SAM 后缀自动机 求子串的不同子串个数)
- HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)
- HDU 4622 本质不同的子串个数:后缀自动机
- HDU 4622 Reincarnation (区间不相同子串个数:字符串哈希 | 后缀数组 | 后缀自动机)
- hdu 4622 Reincarnation (后缀自动机)
- hdu 4622 Reincarnation (后缀自动机)
- HDU 4622 Reincarnation 后缀自动机
- Hdu 4622 Reincarnation 后缀数组/后缀自动机
- HDU4622:Reincarnation(后缀数组,求区间内不同子串的个数)
- HDU 4622 Reincarnation(后缀自动机)
- HDU 4622 Reincarnation SAM
- 后缀自动机(不同子串的个数)hdu4416
- hdu 4622 Reincarnation(后缀树组求子串个数)
- hdu 4622 Reincarnation(后缀数组|后缀自动机|KMP)
- HDU 4622 Reincarnation 后缀数组 或 后缀自动机
- hdu 4622 Reincarnation(SAM)
- HDU 4622 Reincarnation( 任意区间子串的长度, 后缀数组+RMQ)
- hdu 4622 Reincarnation(后缀自动机,入门级)
- ARM汇编器所支持的伪指令
- OpenCV中的矩阵操作
- Win32 application 与 Win32 Console application
- 暑期总结
- Elon Musk(伊隆·马斯克):无限的创想与意志的胜利
- HDU 4622 Reincarnation(SAM 后缀自动机 求子串的不同子串个数)
- Cocos2d-x学习之windows 7的visual studo 2010开发环境安装
- GSL求根
- C#读取Oracle中DATE类型的值,数据表中为空时,怎么去读?
- Qt之对话框设计——利用QPalette改变控件颜色
- 用opencv改变图片大小(像素、尺寸)
- JAVA的类加载机制
- goautodial 安装配置
- OC 将字典写入数组 并将数组写入文件 对文件内容操作