地址:http://codeforces.com/gym/101194

题目:略

思路:

  这题做法挺多的,可以sam也可以后缀数组,我用sam做的。

  1.我自己yy的思路(瞎bb的)

    把第一个串建立sam,然后让其他串在上面跑。

    每走到一个位置p,当前长度为num,就代表这个endpos集合里的长度小于等于num的字符串是被包含了,同时parent树的所有祖先节点也要标记为被包含。

    这一步的具体做法是:用一个mi数组表示到达该节p点时的长度大于mi[p]时,才算未被包含(到达长度指的是从root出发经过某条路径到p的长度),所以其他串在sam上走到每个节点p,长度为num时,记录下mi[p]=max(mi[p],num);

    再跑完所有串后,来更新parent树上的节点。先拓扑排序,然后如果mi[p]>0,mi[fa[p]]=len[p],否则mi[p]=len[fa[p]]。(mi数组初始时为0)

    这样可以在O(n)更新parent树.

    然后再扫一遍节点,如果mi[p]<len[p],anslen=min(anslen,mi[p]+1),这样就得到了anslen。(anslen为最小串的长度)

    在扫一遍节点把所有可行答案求个字典序最小的就行了。(这一步远远没有O(anslen*|p|),p是可行答案集合的大小,时间复杂度可以看下一个做法的时间)

  2.网上看到的做法

    把其他串建立广义sam,然后让第一个串在上面跑。

    这样每当失配的时候,沿parent树走到符合条件的节点p,则此时最小可行字符串长度为len[fa[p]]+2,拿他去更新答案即可。

    这做法时间复杂度更高,因为字符串比较次数比做法一多(它可能比较了长度大于anslen的字符串),且建立sam的时间复杂度也高。

贴个做法2的代码把,一的不想写了

 #include <bits/stdc++.h>

 using namespace std;

 struct SAM
{
static const int MAXN = <<;//大小为字符串长度两倍
static const int LetterSize = ; int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN];
int sum[MAXN], tp[MAXN], cnt[MAXN]; //sum,tp用于拓扑排序,tp为排序后的数组 void init( void)
{
last = tot = ;
len[] = ;
memset( ch[], , sizeof ch[]);
} void add( int x)
{
int p = last, np = last = ++tot;
len[np] = len[p] + , cnt[last] = ;
memset( ch[np], , sizeof ch[np]);
while( p && !ch[p][x]) ch[p][x] = np, p = fa[p];
if( p == )
fa[np] = ;
else
{
int q = ch[p][x];
if( len[q] == len[p] + )
fa[np] = q;
else
{
int nq = ++tot;
memcpy( ch[nq], ch[q], sizeof ch[q]);
len[nq] = len[p] + , fa[nq] = fa[q], fa[q] = fa[np] = nq;
while( p && ch[p][x] == q) ch[p][x] = nq, p = fa[p];
}
}
} void toposort( void)
{
for(int i = ; i <= len[last]; i++) sum[i] = ;
for(int i = ; i <= tot; i++) sum[len[i]]++;
for(int i = ; i <= len[last]; i++) sum[i] += sum[i-];
for(int i = ; i <= tot; i++) tp[sum[len[i]]--] = i;
} void go(char *ss)
{
int mi=0x3f3f3f3f,l;
for(int i=,p=,num=,slen=strlen(ss);i<slen;i++)
{
int c=ss[i]-'a';
if(ch[p][c]) p=ch[p][c],num++;
else
{
while(p&&!ch[p][c]) p=fa[p];
if(p)
num=len[p]+,p=ch[p][c];
else
p=,num=;
if(num+<mi) mi=num+,l=i-num;
else if(num+==mi)
for(int j=l,k=i-num;k<=i;k++,j++)
if(ss[j]!=ss[k])
{
if(ss[j]>ss[k]) l=i-num;
break;
}
}
}
if(mi==0x3f3f3f3f)
printf("Impossible");
else
for(int i=;i<mi;i++)
printf("%c",ss[i+l]);
}
} sam; char sa[],sb[];
int main(void)
{
int t,n,cs=;cin>>t;
while(t--)
{
sam.init();
scanf("%d%s",&n,sa);
for(int i=;i<n;i++)
{
scanf("%s",sb);
for(char *p=sb;*p;p++) sam.add(*p-'a');
sam.last=;
}
printf("Case #%d: ",cs++);
sam.go(sa);
printf("\n");
}
return ;
}

[acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Fantastic Beasts的更多相关文章

  1. UVAL 7902 2016ECfinal F - Mr. Panda and Fantastic Beasts

    题意: 给出n个串,求一个最短的第一个串的子串使它不在其他的n-1个串中出现,若有多个求字典序最小的. Limits: • 1 ≤ T ≤ 42. • 2 ≤ N ≤ 50000. • N ≤ S1 ...

  2. 2016 ACM-ICPC China Finals #F Mr. Panda and Fantastic Beasts

    题目链接$\newcommand{\LCP}{\mathrm{LCP}}\newcommand{\suf}{\mathrm{suf}}$ 题意 给定 $n$ 个字符串 $s_1, s_2, \dots ...

  3. Gym 101194F Mr. Panda and Fantastic Beasts

    #include<bits/stdc++.h> using namespace std; #define ms(arr,a) memset(arr,a,sizeof arr) #defin ...

  4. 2016EC Final F.Mr. Panda and Fantastic Beasts

    题目大意 \(T(1\leq T\leq42)\)组数据,给定\(n(2\leq n\leq 50000)\)个字符串\(S_{i}(n\leq\sum_{i=1}^{n}S_{i}\leq 2500 ...

  5. hdu6007 Mr. Panda and Crystal 最短路+完全背包

    /** 题目:hdu6007 Mr. Panda and Crystal 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6007 题意:魔法师有m能量,有n ...

  6. 2018 China Collegiate Programming Contest Final (CCPC-Final 2018)-K - Mr. Panda and Kakin-中国剩余定理+同余定理

    2018 China Collegiate Programming Contest Final (CCPC-Final 2018)-K - Mr. Panda and Kakin-中国剩余定理+同余定 ...

  7. H - Mr. Panda and Birthday Song Gym - 101775H (动态规划)

    Mrs. Panda’s birthday is coming. Mr. Panda wants to compose a song as gift for her birthday. It is k ...

  8. Gym101194J Mr.Panda and TubeMaster 二分图、费用流

    传送门 看到这张图,是一个网格图,而且有回路限制,不难想到黑白染色. 一般来说我们对一张图黑白染色之后都是黑色点向白色点连边,但是这道题往这边想似乎就想不出建图方法了,因为"一个格子强制流满 ...

  9. Gym 101194C / UVALive 7899 - Mr. Panda and Strips - [set][2016 EC-Final Problem C]

    题目链接: http://codeforces.com/gym/101194/attachments https://icpcarchive.ecs.baylor.edu/index.php?opti ...

随机推荐

  1. 用公式编辑器编辑n元乘积的方法

    在数学中经常会出现很多个元素进行求和或者是乘积的情况,但是在整个数学过程中,不可能将所有的元素都写出来,这样很费时费力同时过程也很赘余,不能很好地理解其中的过程,因此数学中对于这一类的多元相加或者相乘 ...

  2. 怎么绘制旋转Chem3D模型

    化学领域的专业人士常常需要绘制各种化学图形,特别是3D的图形,这个就需要用到一些化学绘图软件.Chem3D是ChemOffice的核心组件之一,可以绘制化学三维模型,包括新建.删除.旋转.移动等基础编 ...

  3. 修改CFileDialog的标题

    CFileDialog   f(TRUE);   f.m_ofn.lpstrTitle   =   "我的标题";   f.DoModal(); 设置标题! CFileDialog ...

  4. D3D中的渲染状态简介

    1). 设置着色模式: SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT) //设置平面着色模式 SetRenderState(D3DRS_SHADEMODE ...

  5. 【BZOJ4606】[Apio2008]DNA DP

    [BZOJ4606][Apio2008]DNA Description 分析如DNA序列这样的生命科学数据是计算机的一个有趣应用.从生物学的角度上说,DNA 是一种由腺嘌呤.胞嘧啶.鸟嘌呤和胸腺嘧啶这 ...

  6. LeetCode-Combination Sum IV

    Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...

  7. SpringBoot--属性加载顺序

    属性加载顺序: 1.在命令行中传入的参数: 2.SPRING_APPLICATION_JSON中的属性:SPRING_APPLICATION_JSON是以JSON格式配置在系统环境变量中内容: 3.j ...

  8. SignalR 循序渐进(四) Hub的生命周期以及IoC

    有阵子没更新这个系列了,最近太忙了.本篇带来的是Hub的生命周期以及IoC. 首先,Hub的生命周期,我们用一个Demo来看看: public class TestHub : Hub { public ...

  9. HAPROXY简介

    HAProxy 是一款高性能TCP/HTTP 反向代理负载均衡服务器,具有如下功能: 根据静态分配的cookies完成HTTP请求转发 在多个服务器间实现负载均衡,并且根据HTTP cookies 实 ...

  10. c#使用FastReports打印

    private void btnprint_Click(object sender, EventArgs e) { //报表路径 string path = Application.StartupPa ...