Gym 101194F Mr. Panda and Fantastic Beasts
来源:互联网 发布:js获取手机app版本号 编辑:程序博客网 时间:2024/06/05 09:27
Gym 101194F Mr. Panda and Fantastic Beasts
2016acm-icpc 中国赛区总决赛 F题
后缀自动机
题意
给n个字符串,找第一个字符串的一个最短子串,使得它不是2到n任何一个字符串的子串。输出字典序最小的。
思路
SAM。算半个裸题?
%%%
把2到n用特殊字符连接起来(‘z’+1),拼成一个字符,构建sam。然后用第一个字符串跟他匹配,每次失配时更新答案。
sam的每个状态代表一系列子串,我们需要取一个最小的。留下minlen数组也可以,如果不留下minlen数组,那么每个状态的最小长度就是沿着失配边走第一个状态的最大长度加1。每次失配更新答案长度与字典序,然后沿着失配边走,这个过程就是缩小目前可匹配的子串的过程,类似kmp。沿着失配边走不了的时候,要么是可以接着匹配了,要么是走到起点了,开始下一轮的匹配。
代码
注意长度和字典序的写法。。因为zz错误对拍半天。。。唉
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <ctime> #include <vector> #include <queue> #include <stack> #include <deque> #include <string> #include <map> #include <set> #include <list> #define M(a,b) memset(a,b,sizeof(a))typedef long long LL;using namespace std;const int MAXL=1000005;const int MAXS=27;const int oo=0x3f3f3f3f;struct SAM{ int n=0, st; //maxlen表示每个状态对应的子串中长度最大值,minlen最小值 //trans是转移边,根节点是1,所以0代表不存在 //slink表示绿色的suffix link //col表示节点颜色,col=1代表是后缀节点,=0代表不是后缀的节点 //indeg表示对于只含有suffix link的图的度,统计endposamu用 //endposa表示该状态对应的子串们出现的结尾位置,amu表示endpos集合的大小,也表示该状态对应的子串的重复次数 //ans表示某一长度的子串的个数 int maxlen[2*MAXL+10], trans[2*MAXL+10][MAXS], slink[2*MAXL+10]; int new_state(int _maxlen, int* _trans, int _slink) { n++; maxlen[n]=_maxlen; for(int i=0; i<MAXS; i++) { if(_trans==NULL) trans[n][i]=0; else trans[n][i]=_trans[i]; } slink[n]=_slink; return n; } int add_char(char ch, int u) { int c=ch-'a'; int z=new_state(maxlen[u]+1, NULL, 0); int v=u; while(v!=0&&trans[v][c]==0) { trans[v][c]=z; v=slink[v]; } if(v==0)//最简单的情况,suffix-path(u->S)上都没有对应字符ch的转移 { slink[z]=1; return z; } int x=trans[v][c]; if(maxlen[v]+1==maxlen[x])//较简单的情况,不用拆分x { slink[z]=x; return z; } int y=new_state(maxlen[v]+1, trans[x], slink[x]); //最复杂的情况,拆分x slink[x]=y;slink[z]=y; int w=v; while(w!=0&&trans[w][c]==x) { trans[w][c]=y; w=slink[w]; } return z; } void init() { n=0; memset(maxlen, 0, sizeof(maxlen)); memset(trans, 0, sizeof(maxlen)); memset(slink, 0, sizeof(maxlen)); st=new_state(0, NULL, 0); } void addstring(string s) { int la=st; for(auto tmp:s) { la=add_char(tmp, la); } }}sam;pair<int,int> match(string s){ int now=sam.st, l=0; int ans=oo;int lp=0, rp=oo; for(int i=0;i<s.size();i++) { int x=s[i]-'a'; if(sam.trans[now][x])// now=sam.trans[now][x], l=sam.maxlen[sam.slink[now]]+1; else { while(now&&!sam.trans[now][x]) { if(l+1<ans) { ans=l+1; lp=i-l;rp=i; } else if(l+1==ans) { for(int j=1;j<=l+1;j++) { if(s[i-l+j-1]<s[lp+j-1]) { lp=i-l;rp=i; break; } else if(s[i-l+j-1]>s[lp+j-1]) break; } } now=sam.slink[now], l=sam.maxlen[sam.slink[now]]+1; } if(!now) now=sam.st, l=0; else now=sam.trans[now][x], l=sam.maxlen[sam.slink[now]]+1; } } return make_pair(lp, rp);}int main(){ int T;scanf("%d", &T);int cas=0; while(T--) { sam.init(); int n;scanf("%d", &n); string s0;cin>>s0; string s, s1;cin>>s; for(int i=2;i<n;i++) { cin>>s1; s+=('z'+1); s+=s1; } sam.addstring(s); pair<int, int> p=match(s0); printf("Case #%d: ", ++cas); if(p.second>s.length()) printf("Impossible\n"); else { for(int i=p.first;i<=p.second;i++) { printf("%c", s0[i]); } printf("\n"); } } return 0;}
阅读全文
0 0
- Gym 101194F Mr. Panda and Fantastic Beasts
- 2016 China Final F Mr. Panda and Fantastic Beasts
- Gym101194F-Mr. Panda and Fantastic Beasts
- [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Fantastic Beasts 后缀自动机
- 【Gym】101194J Mr.Panda and TubeMaster
- BJ模拟 Mr. Panda and Fantastic Beats(广义后缀自动机、trie树上后缀自动机)
- HDU6007-Mr. Panda and Crystal
- Gym101194C-Mr. Panda and Strips
- Mr. Panda and Crystal HDU
- Problem I. Mr. Panda and Crystal
- [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr.Panda and TubeMaster
- [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Strips 暴力+剪枝
- HDU 6007 Mr. Panda and Crystal (最短路 + 完全背包)
- [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr.Panda and TubeMaster费用流
- hdu 6007 Mr. Panda and Crystal(最短路+完全背包)
- Codeforces 101206 I & HDU 6007 Mr. Panda and Crystal
- Hdu 6007 Mr. Panda and Crystal 最短路+完全背包
- Gym 101246F list and iterator
- Codeforces 432D Prefixes and Suffixes (next数组的应用)
- Android TV使用属性动画绘制平移焦点框
- 【Laravel Excel译文】——导出
- tcpdump实用用法
- 最常见的管理误区,你中招了吗?
- Gym 101194F Mr. Panda and Fantastic Beasts
- JavaScript(4)__Js基础<字符串>
- 澳门拥抱阿里云:全面应用智能技术,为城市装上“大脑”
- domain和cluster结合让nodejs更加健壮的运行
- JAVA 导入EXCEL文档
- http简介
- 新手学xingo golang服务器之-golang和unity3d的Protobuf生成(三)
- Java搞定面试中的二叉树题目
- laravel各种路径的获取方法