题目:

Problem F. Mr. Panda and Fantastic Beasts

题意:

有 n 个字符串,求第一个字符串的最短子串,满足这个子串在其余 n-1 个字符串中都没有出现过。

思路:

因为所有串的长度和小于等于250000,所以可以把这 n 个串合成一个串,为避免产生本不属于这些串的子串,每个串后都要加一个结束符,且把第一个串放在最后(这样就可以求后缀获得)。

例:

3

aba

cd

ab

合并后变成:cd*ab*aba 。

然后,求第一个串的所有后缀(也就是合并后串的后缀:aba、ba、a)与合并后串除这些后缀之外的其他后缀的最长公共前缀,所得的最长公共前缀再加之后的一个字母就是答案。求所有答案里最短的,长度一样求字典序最小的。

Code:

#include<bits/stdc++.h>
using namespace std;typedef long long ll;const int MAX = 3e5+10;
const ll mod = 1e9+7;/**倍增算法nlogn*将待排序数组放在0~n-1中,在最后补一个0*build(,n+1,);//注意是n+1*getHeight(,n);*例如:*n   = 8;*num[]   = { 1, 1, 2, 1, 1, 1, 1, 2, $ };注意num最后一位为0,其他大于0*Rank[]  = { 4, 6, 8, 1, 2, 3, 5, 7, 0 };Rank[0~n-1]为有效值,Rank[n]必定为0无效值*sa[]    = { 8, 3, 4, 5, 0, 6, 1, 7, 2 };sa[1~n]为有效值,sa[0]必定为n是无效值*height[]= { 0, 0, 3, 2, 3, 1, 2, 0, 1 };height[2~n]为有效值
*/string arr,tmp;
char fin[MAX];
char str[MAX];
int s[MAX];
bool vis[MAX];
int t1[MAX],t2[MAX],c[MAX],sa[MAX],rk[MAX],height[MAX];void init()
{memset(vis,0,sizeof(vis));memset(t1,0,sizeof(t1));memset(t2,0,sizeof(t2));memset(c,0,sizeof(c));memset(sa,0,sizeof(sa));memset(rk,0,sizeof(rk));memset(height,0,sizeof(height));
}//求SA数组
void get_SA(int s[],int n,int m){int *x=t1,*y=t2;for(int i=0;i<m;i++)    c[i]=0;for(int i=0;i<n;i++)    c[x[i]=s[i]]++;for(int i=1;i<m;i++)    c[i]+=c[i-1];for(int i=n-1;i>=0;i--)     sa[--c[x[i]]]=i;for(int k=1;k<=n;k<<=1){int p=0;for(int i=n-k;i<n;i++)  y[p++]=i;for(int i=0;i<n;i++)    if(sa[i]>=k)    y[p++]=sa[i]-k;for(int i=0;i<m;i++)    c[i]=0;for(int i=0;i<n;i++)    c[x[y[i]]]++;for(int i=0;i<m;i++)    c[i]+=c[i-1];for(int i=n-1;i>=0;i--)    sa[--c[x[y[i]]]]=y[i];swap(x,y);p=1;x[sa[0]]=0;for(int i=1;i<n;i++)x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k] ? p-1:p++;if(p>=n)    break;m=p;}
}//求height和rank数组
void get_height(int s[],int n)
{int k=0;for(int i=0;i<=n;i++)rk[sa[i]]=i;for(int i=0;i<n;i++){if(k) k--;int j=sa[rk[i]-1];while(s[i+k]==s[j+k]) k++;height[rk[i]]=k;}
}string ans;
string tmpans1;
string tmpans2;int main()
{int T;cin>>T;int Case=1;while(T--){arr.clear();int n;cin>>n;scanf("%s",fin);for(int i=1;i<n;i++){cin>>tmp;tmp+='0'; //结束符arr+=tmp;}int len=0;for(int i=0;i<arr.size();i++){if(arr[i]=='0')     s[len++]=1;else    s[len++]=arr[i]-'a'+2;}int pos=len;for(int i=0;i<strlen(fin);i++){arr+=fin[i];s[len++]=fin[i]-'a'+2;}s[len]=0;init();get_SA(s,len+1,40);get_height(s,len);//把第一个串的所有后缀标记for(int i=pos;i<len;i++){vis[rk[i]]=true;}ans="";int cnt=1e9+7;tmpans1="";tmpans2="";for(int i=pos;i<len;i++){int now = rk[i];int tmpmi=1e9+7;int fg=0;int fg1=0,fg2=0;int tmpmi1=1e9+7;int tmpmi2=1e9+7;tmpans1="";tmpans2="";//从当前排名往左找最长公共前缀if(now==1){tmpmi1=-1;}for(int j=now;j>=2;j--){tmpmi=min(tmpmi,height[j]);if(!vis[j-1]){tmpmi1=tmpmi;if(sa[now]+tmpmi<arr.size()){fg1=1;tmpans1="";tmpans1.assign(arr,sa[now],tmpmi1+1);}else    fg=1;break;}}//从当前排名往右找最长公共前缀if(now==len){tmpmi2=-1;}tmpmi=1e9+7;for(int j=now+1;j<=len;j++){tmpmi=min(tmpmi,height[j]);if(!vis[j]){tmpmi2=tmpmi;if(sa[now]+tmpmi<arr.size()){fg2=1;tmpans2="";tmpans2.assign(arr,sa[now],tmpmi2+1);}else fg=1;break;}}//取两者中的最坏情况为这种情况下的最优可行解//再与之前的最优解比较if(fg==1)   continue;if(fg1==0&&fg2==0)  continue;else if(fg1!=0&&fg2==0){if(tmpmi1+1<cnt||(tmpmi1+1==cnt&&tmpans1<ans)){ans=tmpans1;cnt=ans.size();}}else if(fg1==0&&fg2!=0){if(tmpmi2+1<cnt||(tmpmi2+1==cnt&&tmpans2<ans)){ans=tmpans2;cnt=ans.size();}}else{if(tmpmi1>tmpmi2){if(tmpmi1+1<cnt||(tmpmi1+1==cnt&&tmpans1<ans)){ans=tmpans1;cnt=ans.size();}}else{if(tmpmi2+1<cnt||(tmpmi2+1==cnt&&tmpans2<ans)){ans=tmpans2;cnt=ans.size();}}}}printf("Case #%d: ",Case++);if(cnt==1e9+7)       cout<<"Impossible"<<endl;else    cout<<ans<<endl;}return 0;
}

Mr. Panda and Fantastic Beasts(EC2016 后缀数组)相关推荐

  1. Gym - 101194F(后缀数组)

    Mr. Panda and Fantastic Beasts 题意 给出若干个字符串,找到一个最短的字典序最小的字符串且仅是第一个字符串的子串. 分析 对于这种多个字符串.重复的子串问题一般都要连接字 ...

  2. luoguP5108 仰望半月的夜空 [官方?]题解 后缀数组 / 后缀树 / 后缀自动机 + 线段树 / st表 + 二分...

    仰望半月的夜空 题解 可以的话,支持一下原作吧... 这道题数据很弱..... 因此各种乱搞估计都是能过的.... 算法一 暴力长度然后判断判断,复杂度\(O(n^3)\) 期望得分15分 算法二 通 ...

  3. 寻找一个字符串的重复子串 后缀数组

    什么是后缀数组 令字符串 S=S[1]S[2]...S[n]S=S[1]S[2]...S[n]{\displaystyle S=S[1]S[2]...S[n]} , S[i,j]S[i,j]{\dis ...

  4. 【2012百度之星/资格赛】H:用户请求中的品牌 [后缀数组]

    时间限制: 1000ms 内存限制: 65536kB 描述 馅饼同学是一个在百度工作,做用户请求(query)分析的同学,他在用户请求中经常会遇到一些很奇葩的词汇.在比方说"johnsonj ...

  5. Boring counting HDU - 3518 (后缀数组)

    Boring counting \[ Time Limit: 1000 ms \quad Memory Limit: 32768 kB \] 题意 给出一个字符串,求出其中出现两次及以上的子串个数,要 ...

  6. HDU4080 Stammering Aliens(二分 + 后缀数组)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4080 Description Dr. Ellie Arroway has establish ...

  7. 后缀数组 + Hash + 二分 or Hash + 二分 + 双指针 求 LCP ---- 2017icpc 青岛 J Suffix (假题!!)

    题目链接 题目大意: 就是给你n个串每个串取一个后缀,要求把串拼起来要求字典序最小!! sum_length_of_n≤5e5sum\_length\_of\_n\leq 5e5sum_length_ ...

  8. 后缀数组 ---- 2018~2019icpc焦作H题[后缀数组+st表+二分+单调栈]

    题目链接 题目大意: 给出nnn个数,定义f[l,r]f[l,r]f[l,r]表示 区间[l,r][l,r][l,r]的最大值,求所有 子区间的最大值的和,要求相同的子区间只能算一次 比如数列 5 6 ...

  9. [Ahoi2013]差异[后缀数组+单调栈]

    链接 解题思路:很明显前面∑1<=i<j<=nlen(Ti)+len(Tj)\sum_{1<=i<j<=n}len(T_i)+len(T_j)∑1<=i< ...

  10. poj2217详解 ( 后缀数组 + 高度数组 )

    题目大概意思就是 给两个字符串,求最长公共字符串子串长度 我们可以考虑用后缀数组和高度数组 一个字符串 中 最长的两个相同字符串长度, 不就是 后缀数组中相邻两个后缀的最长公共前缀, 不就是 高度数组 ...

最新文章

  1. R Learnilng 十八讲1-6
  2. Extensible Messaging and Presence Protocol (XMPP): Core
  3. SQL优化这么做就对了
  4. 【MaxCompute】学习笔记基础说明
  5. Mingw-W64编译Windows程序提示:undefined reference to `__imp_GetStockObject' 的解决方法
  6. IDEA 2021.1.2中scala生成变量自动勾选specify type
  7. 前端解析返回的对象时json显示$ref问题的解决
  8. 博士读了12年,一篇文章没有
  9. Leaflet文档阅读笔记-Leaflet on Mobile笔记
  10. h2database连接字符串
  11. 新希望:拟参与设立总规模40亿元的广西新希望生猪保供专项产业基金
  12. C#通用验证类:邮箱,电话,手机,数字,英文,日期,身份证,邮编,网址,IP
  13. HTML 5 会让iOS和Android开发者转行吗?
  14. JavaWeb-MVC模式概述
  15. office 2010 安装时出错 MSXML版本6.10.1129.0终极解决方案
  16. 中职学校计算机课听课记录表,中职语文听课记录模板
  17. 仿邓杰作品(艺家网站)总结
  18. Windows系统操作快捷键---百度百科
  19. 这一季绿色智能制造“英雄联盟”已集结, 有哪些新鲜点?
  20. 10+ 小故事揭秘高频「操作系统面试题」

热门文章

  1. java 分隔符_Java分隔符的使用
  2. maven-replacer-plugin 静态资源打包方案js css
  3. 有钱任性的农夫山泉,被迫踏上IPO?
  4. 计算机保研个人简介,保研个人简历模板
  5. 咸鱼的 Github 情报 | 一个支持边下边播、无版权限制和自动上传的BT离线下载程序...
  6. 高清渐变动态壁纸来了 手把手教你做动态壁纸
  7. 修改elementui 的默认样式element.style样式
  8. [Unity]DrawLine与DrawRay的区别
  9. SpringBoot入门,快速搭建简单Web应用环境
  10. Detecting Spacecraft Anomalies Using LSTMs and Nonparametric Dynamic Thresholding