hdu 6138 Fleet of the Eternal Throne
来源:互联网 发布:淘宝天天疯狂购入口 编辑:程序博客网 时间:2024/05/24 07:22
后缀数组
之前一直以为把多个串连起来也是用同一个特殊字符,傻了。。这样会导致height数组的值可能包括特殊字符的长度。应该用不同的字符连接起来。此处因为可能有很多个串,所以合法数字就是0-25, 剩下的数字都是用来连接不同串的。
比较麻烦的就是查询的时候。
#include<iostream>#include<algorithm>#include<cstdlib>#include<cstdio>#include<cstring>#include<vector>#include<cmath>#include<complex>#include<queue>#define T 111111using namespace std;int s[T];int t1[T],t2[T],cc[T],x[T],sa[T],Rank[T],height[T], belong[T], is[T];int len;bool cmp(int *y,int a,int b,int k){ int a1=y[a]; int b1=y[b]; int a2=a+k>=len ? -1:y[a+k]; int b2=b+k>=len ? -1:y[b+k]; return a1==b1 && a2==b2;}void make_sa(){ int *x=t1,*y=t2; int m=26+100000; for(int i=0; i<m; i++) cc[i]=0; for(int i=0; i<len; i++) ++cc[x[i]=s[i]]; for(int i=1; i<m; i++) cc[i]+=cc[i-1]; for(int i=len-1; i>=0; i--) sa[--cc[x[i]]]=i; for(int k=1; k<=len; k<<=1) { int p=0; for(int i=len-k; i<len; i++) y[p++]=i; for(int i=0; i<len; i++) if( sa[i]>=k ) y[p++]=sa[i]-k; for(int i=0; i<m; i++) cc[i]=0; for(int i=0; i<len; i++) ++cc[x[y[i]]]; for(int i=1; i<m; i++) cc[i]+=cc[i-1]; for(int i=len-1; i>=0; i--) sa[--cc[x[y[i]]]]=y[i]; swap(x,y); m=1; x[sa[0]]=0; for(int i=1; i<len; i++) x[sa[i]]=cmp(y,sa[i],sa[i-1],k) ? m-1:m++; if( m>=len ) break; }}void make_height(){ for(int i=0; i<len; i++) Rank[sa[i]]=i; height[0]=0; int k=0; for(int i=0; i<len; i++) { if(!Rank[i]) continue; int j=sa[Rank[i]-1]; if(k) k--; while(s[i+k]==s[j+k]) k++; height[Rank[i]]=k; }}int main(){ char buff[100010]; int L[100010], ok; int cas, cnt=27; int n, m, x, y; scanf("%d", &cas); while(cas--) { scanf("%d", &n); len=0; memset(belong, 0, sizeof(belong)); memset(L, 0, sizeof(L)); for(int j=1; j<=n; j++) { scanf("%s", buff); for(int i=len; i<len+strlen(buff); i++) { //is[i]==1表示这个串是符合规定的包含一个完整前缀的串 if(i==len) is[i]=1; else is[i]=0; s[i]=buff[i-len]-'a'; //belong[i]是指第i个字符属于第几个串,串的标号从1开始 belong[i]=j; } L[j]=strlen(buff); len+=strlen(buff); s[len++]=cnt++; } s[--len]='\0'; make_sa(); make_height(); scanf("%d", &m); while(m--) {//flagx表示x的当前值,flag表示符合规定的包含一个完整前缀的串的长度 int flagx=0, flagy=0, flag=0, ans=0; scanf("%d%d", &x, &y); for(int i=0; i<len-1; i++) { //belong为0的值都是用来分格的数字开头的串,不用操作 if(!belong[sa[i]]) continue; if(is[sa[i]]==1) { //如果找到一个符合规定的包含一个完整前缀的串 if(belong[sa[i]]==x) { ans=max (ans, flagy); flagx=height[i+1]; } else if(belong[sa[i]]==y) { ans=max(ans, flagx); flagy=height[i+1]; } else ans=max(ans, min(flagx, flagy)); flag=height[i+1]; } else if(belong[sa[i]]==x) { ans=max(ans, min(flagy, flag)); flagx=height[i+1]; } else if(belong[sa[i]]==y) { ans=max(ans, min(flagx, flag)); flagy=height[i+1]; } //因为是取min值,每次读入一个串都要把三个值更新一下 flag =min(flag, height[i+1]); flagx=min(flagx, height[i+1]); flagy=min(flagy, height[i+1]); } printf("%d\n", ans); } } return 0;}
阅读全文
0 0
- HDU 6138 Fleet of the Eternal Throne
- hdu 6138 Fleet of the Eternal Throne
- HDU 6138 Fleet of the Eternal Throne
- HDU 6138 Fleet of the Eternal Throne (2017多校8
- HDU 6138 Fleet of the Eternal Throne (2017多校8
- HDU 6138 Fleet of the Eternal Throne ( AC自动机)
- hdu 6138 Fleet of the Eternal Throne (ac自动机)
- HDU 6138 Fleet of the Eternal Throne [AC自动机]
- HDU 6138 Fleet of the Eternal Throne (AC自动机)
- hdu 6138 Fleet of the Eternal Throne(AC自动机)
- HDU 6138 Fleet of the Eternal Throne(AC自动机)
- HDU 6138 Fleet of the Eternal Throne AC自动机
- HDU6138 Fleet of the Eternal Throne
- HDU 6138 Fleet of the Eternal Throne(2017 Multi-University Training Contest 8)
- HDU 6138 2017多校第八场1006 Fleet of the Eternal Throne :AC自动机
- HDU 6138 Fleet of the Eternal Throne AC自动机||后缀数组
- HDU 6138 Fleet of the Eternal Throne 多校#8 AC自动机
- hdu 6138 Fleet of the Eternal Throne 基于kmp算法的求解
- HDU 6136 Death Podracing (2017 Multi-Univ Training Contest 8)
- 关于项目导入的问题
- 从尾到头打印链表
- 【HDU6153 2017中国大学生程序设计竞赛
- uml类图基础
- hdu 6138 Fleet of the Eternal Throne
- C++栈解退
- AspNetPager真假分页
- Kanade's trio
- Java8新特性
- Hibernate异常
- Java多线程JUC
- spring4.2+struts2.5+jdbc实例-PIMS(四)
- 互联网公益陷入信任危机,智慧公益能否力挽狂澜?