题目大意

\(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. 机器学习-逻辑回归与SVM的联系与区别

    (搬运工) 逻辑回归(LR)与SVM的联系与区别 LR 和 SVM 都可以处理分类问题,且一般都用于处理线性二分类问题(在改进的情况下可以处理多分类问题,如LR的Softmax回归用在深度学习的多分类 ...

  2. mesos是什么

    听过不少人在讨论 Mesos,然而并不是很明白 Mesos 到底能够解决什么问题,使用场景是怎样的,周伟涛(国内较早一批接触使用 Docker,Mesos 等技术的开发者)用一句话形容它, Mesos ...

  3. Python json库中load、loads、dump、dumps的区别与用法

    1 json.loads() 将json格式的数据转化为字典类型 data_json = '{"msg": "登录成功", "code": ...

  4. 布客&#183;ApacheCN 编程/大数据/数据科学/人工智能学习资源 2020.2

    特约赞助商 公告 我们愿意普及区块链技术,但前提是互利互惠.我们有大量技术类学习资源,也有大量的人需要这些资源.如果能借助区块链技术存储和分发,我们就能将它们普及给我们的受众. 我们正在招募项目负责人 ...

  5. [USACO19JAN]Exercise Route P

    先让我们探索一下两条非树边以及树边能构成简单环的条件是什么,你会发现将第一条非树边的两个点在树上形成的链记为 \(W_1\),另一条即为 \(W_2\),那么当且仅当 \(W_1, W_2\) 有交时 ...

  6. 微信公众号之微信登录失败,redirect_uri域名与后台配置不一致,错误代码10003

    前几次也遇到过这个问题:没有注意,今天记一下 解决:把你出错页面的url复制出来,看下域名是多少,然后在相应的微信公众号位置加上该域名即可 第一步:登录微信公众号: 第二步:将文件下载后,利用工具传入 ...

  7. urlencode编码与urldecode解码

    转载请注明来源:https://www.cnblogs.com/hookjc/ <script type="text/javascript"><!--functi ...

  8. 前端开发Grunt工具的安装使用

    随着前端开发效果越来越丰富,前端的结构也越来越复杂,这个时候就需要一个工具来进行管理,可以帮你做语法校验,文件拼接,代码压缩,文件清理等等琐事,Grunt就是这么一个不错的工具. 安装并不复杂,只要先 ...

  9. 学习jsp篇:jsp简单实例之二登录

    编程环境:IDEA,Tomcat,JavaEE 一.实例二登录 1.在自己建的工程下的web目录下建一个文件夹为login,在login中编写登录代码(其实就是和实例一同一个项目) 2.先建登录页面j ...

  10. sql作业题

    作业题:1.查询选修课程'3-105'且成绩在60到80之间的所有记录.注释:用于指定某个范围使用between and,也可以使用and连接符;答案:法1:select * from sc wher ...