题目大意

\(T(1\leq T\leq42)\)组数据,给定\(n(2\leq n\leq 50000)\)个字符串\(S_{i}(n\leq\sum_{i=1}^{n}S_{i}\leq 250000\),所有\(T\)的\(\sum S_{i}\leq 3 \times 10^6)\)求出一个最短的字符串,其仅为第\(1\)个字符串的字串(有多个长度相同的则求其中字典序最小的)。

思路

我们考虑用一个特殊字符将所有字符串串成一个串,求出该串的\(sa[\space]\)与\(lcp[\space]\),我们考虑从第一个串范围内开始的每一个后缀\(sa[i]\),找出在后缀数组中的前一个以及后一个起点不在第一个串内的后缀\(pred[i],succ[i]\)(更远的后缀与其的\(lcp\)不会更大,所以仅需一前一后最近的两个即可),我们可以对\(lcp[\space]\)做\(rmq\)来求出\(max(lcp(sa[i],pred[i]),lcp(sa[i],succ[i]))\),如果最长公共前缀为\(n\),说明以\(i\)这个位置为起点的第一个串长为\(1\sim n\)的字串都在其他串中出现过,所以以\(i\)这个位置为起点的长为\(n+1\)的第一个串的字串就是最短的以\(i\)这个位置为起点的满足要求的串(注意判断一下这个串的合法性,可能超出第一个串的范围),我们对后缀数组从前往后遍历,不断更新答案,于是可以求出在最短的情况下字典序最小的串。

代码

#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
#define all(x) x.begin(),x.end()
//#define int LL
//#define lc p*2+1
//#define rc p*2+2
#define endl '\n'
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#pragma warning(disable : 4996)
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const double eps = 1e-8;
const LL MOD = 1000000007;
const LL mod = 998244353;
const int maxn = 500010; int T, N, cnt = 0;
string SS, t;
int n, k;
int rk[maxn], tmp[maxn], sa[maxn], lcp[maxn], flen, pred[maxn], succ[maxn]; bool compare_sa(int i, int j)
{
if (rk[i] != rk[j])
return rk[i] < rk[j];
else
{
int ri = i + k <= n ? rk[i + k] : -1;
int rj = j + k <= n ? rk[j + k] : -1;
return ri < rj;
}
} void construct_sa(string S, int* sa)
{
n = S.length();
for (int i = 0; i <= n; i++)
{
sa[i] = i;
rk[i] = i < n ? S[i] : -1;
}
for (k = 1; k <= n; k *= 2)
{
sort(sa, sa + n + 1, compare_sa);
tmp[sa[0]] = 0;
for (int i = 1; i <= n; i++)
tmp[sa[i]] = tmp[sa[i - 1]] + (compare_sa(sa[i - 1], sa[i]) ? 1 : 0);
for (int i = 0; i <= n; i++)
rk[i] = tmp[i];
}
} void construct_lcp(string S, int* sa, int* lcp)
{
int n = S.length();
for (int i = 0; i <= n; i++)
rk[sa[i]] = i;
int h = 0;
lcp[0] = 0;
for (int i = 0; i < n; i++)
{
int j = sa[rk[i] - 1];
if (h > 0)
h--;
for (; j + h < n && i + h < n; h++)
{
if (S[j + h] != S[i + h])
break;
} lcp[rk[i] - 1] = h;
}
} int ST[maxn][30]; void LCP_init(int n)
{
for (int i = 0; i < n; i++)
ST[i][0] = lcp[i];
for (int j = 1; (1 << j) <= n; j++)
{
for (int i = 0; i + (1 << j) - 1 < n; i++)
ST[i][j] = min(ST[i][j - 1], ST[i + (1 << (j - 1))][j - 1]);
}
} int LCP(int l, int r)//[l,r)
{
if (l >= r)
return 0;
int k = floor(log2(r - l)); return min(ST[l][k], ST[r - (1 << k)][k]);
} void solve()
{
int len = SS.length(), ans = -1, sou = -1;
construct_sa(SS, sa);
construct_lcp(SS, sa, lcp);
LCP_init(len);
int temp = 0;
for (int i = 1; i <= len; i++)
{
if (sa[i] >= flen)
temp = i;
else
pred[i] = temp;//前一个最近的从第一个字串外开始的后缀
}
temp = 0;
for (int i = len; i >= 1; i--)
{
if (sa[i] >= flen)
temp = i;
else
succ[i] = temp;//后一个最近的从第一个字串外开始的后缀
}
for (int i = 1; i <= len; i++)
{
int mx = 0;
if (sa[i] < flen)
{
if (pred[i])
mx = max(mx, LCP(pred[i], i));
if (succ[i])
mx = max(mx, LCP(i, succ[i]));
if ((ans == -1 || ans > mx + 1) && sa[i] + mx + 1 <= flen)
ans = mx + 1, sou = sa[i];
}
}
if (ans == -1)
cout << "Case #" << cnt << ": Impossible" << endl;
else
{
cout << "Case #" << cnt << ": ";
for (int i = sou; i < sou + ans; i++)
cout << SS[i];
cout << endl;
}
} int main()
{
IOS;
cin >> T;
while (T--)
{
cnt++;
memset(pred, 0, sizeof(pred));
memset(succ, 0, sizeof(succ));
cin >> N >> SS;
flen = SS.size();
for (int i = 2; i <= N; i++)
{
cin >> t;
SS += '#' + t;
}
solve();
} return 0;
}

2016EC Final F.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. [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Fantastic Beasts

    地址:http://codeforces.com/gym/101194 题目:略 思路: 这题做法挺多的,可以sam也可以后缀数组,我用sam做的. 1.我自己yy的思路(瞎bb的) 把第一个串建立s ...

  4. Gym 101194F Mr. Panda and Fantastic Beasts

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

  5. ICPC 2016 China Final J. Mr.Panda and TubeMaster【最大费用最大流】

    有一种限制下界强制选的,但是也可以不用 把每个格点拆成两个,一个连s一个连t,对于不是必选的连中间连流量1费用0边表示不选,然后黑白染色,黑点连横着白点连竖着,边权就是这条水管的权值,然后跑最大费用最 ...

  6. 【费用流】 ICPC 2016 China Final J. Mr.Panda and TubeMaster

    表示“必须选”的模型 题目大意 题目分析 一个格子有四种方式看上去很难处理.将横竖两个方向分开考虑,会发现:因为收益只与相邻格子是否连通有关,所以可以将一个格子拆成表示横竖两个方向的,互相独立的点. ...

  7. China Final J - Mr.Panda and TubeMaster

    和一般的管道不同 不能类似“无限之环”或者“弯弯国”的建图,因为这两个题都是某些位置必须有,或者必须没有 但是本题可以有的位置随意,不能限制某个位置要么流2,要么流0,(实际上可能流了1过去) 所以建 ...

  8. 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-中国剩余定理+同余定 ...

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

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

随机推荐

  1. IoC容器-Bean管理(bean生命周期)

    1,生命周期 即从对象创建到对象销毁的过程 2,bean生命周期 (1)通过构造器创建bean实例(无参数构造) (2)为bean的属性设置值和对其他bean的引用(调用set方法) (3)调用bea ...

  2. 集合框架-LinkedHashSet集合(有序唯一)

    1 package cn.itcast.p4.hashset.demo; 2 3 import java.util.HashSet; 4 import java.util.Iterator; 5 im ...

  3. collate utf8_bin是什么意思

    创建数据库时 collate utf_bin是 以二进制值比较,也就是区分大小写,collate是核对的意思 uft-8_general_ci  一般比较,不区分大小写

  4. IEEE754浮点数表示法

    IEEE二进制浮点数算术标准(ANSI/IEEE Std 754-1985)是一套规定如何用二进制表示浮点数的标准.就像"补码规则"建立了二进制位和正负数的一一对应关系一样,IEE ...

  5. python07day

    回顾 id == is: ==: 数值是否相同 is: 内存地址是否相同 id: 获取对象的内存地址 代码块: 一个文件.交互式命令一行都是一个代码块 同一代码块下缓存机制(字符串驻留机制) 所有数字 ...

  6. contos 6.9 和 centos7 配置docker?

    一.contos 6.9 配置docker? 1.检查centos的内核,因为目前docker的版本所支持的centos最低内核版本为2.4 // uname -r // 2.6.32-696.el6 ...

  7. NumPy 教程目录

    NumPy 教程目录 1 Lesson1--NumPy NumPy 安装 2 Lesson2--NumPy Ndarray 对象 3 Lesson3--NumPy 数据类型 4 Lesson4--Nu ...

  8. Angular中$broadcast和$emit的使用方法

    要在控制器之间传递变量变化需要使用angular中的$broadcast和$emit方法来传递,同时使用$on来接收事件并作出响应. broadcast译为广播,即上级传递下级. 示例代码: < ...

  9. Maven 警告 expected START_TAG or END_TAG not TEXT

    原因 在Maven警告提示区域存在空格等不规范字符,在网上复制到项目中时经常出现类似问题. pop.xml文件,setting.xml文件极易出现此类问题. 解决 将空格删除,规范一下格式就好了. 示 ...

  10. Java UDP实现聊天功能代码【转】

    感谢大佬大佬!!!:https://www.cnblogs.com/woshijpf/p/3735684.html 我以前经常写的是基于TCP的网络编程,由于TCP建立连接鼻血要经过三次握手连接,服务 ...