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 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的更多相关文章
- UVAL 7902 2016ECfinal F - Mr. Panda and Fantastic Beasts
题意: 给出n个串,求一个最短的第一个串的子串使它不在其他的n-1个串中出现,若有多个求字典序最小的. Limits: • 1 ≤ T ≤ 42. • 2 ≤ N ≤ 50000. • N ≤ S1 ...
- 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 ...
- [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Fantastic Beasts
地址:http://codeforces.com/gym/101194 题目:略 思路: 这题做法挺多的,可以sam也可以后缀数组,我用sam做的. 1.我自己yy的思路(瞎bb的) 把第一个串建立s ...
- Gym 101194F Mr. Panda and Fantastic Beasts
#include<bits/stdc++.h> using namespace std; #define ms(arr,a) memset(arr,a,sizeof arr) #defin ...
- ICPC 2016 China Final J. Mr.Panda and TubeMaster【最大费用最大流】
有一种限制下界强制选的,但是也可以不用 把每个格点拆成两个,一个连s一个连t,对于不是必选的连中间连流量1费用0边表示不选,然后黑白染色,黑点连横着白点连竖着,边权就是这条水管的权值,然后跑最大费用最 ...
- 【费用流】 ICPC 2016 China Final J. Mr.Panda and TubeMaster
表示“必须选”的模型 题目大意 题目分析 一个格子有四种方式看上去很难处理.将横竖两个方向分开考虑,会发现:因为收益只与相邻格子是否连通有关,所以可以将一个格子拆成表示横竖两个方向的,互相独立的点. ...
- China Final J - Mr.Panda and TubeMaster
和一般的管道不同 不能类似“无限之环”或者“弯弯国”的建图,因为这两个题都是某些位置必须有,或者必须没有 但是本题可以有的位置随意,不能限制某个位置要么流2,要么流0,(实际上可能流了1过去) 所以建 ...
- 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-中国剩余定理+同余定 ...
- hdu6007 Mr. Panda and Crystal 最短路+完全背包
/** 题目:hdu6007 Mr. Panda and Crystal 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6007 题意:魔法师有m能量,有n ...
随机推荐
- Nginx全面介绍 什么是Nginx?
目录 一:Nginx全面讲解 1.简介: 2.nginx的用武之地 3.关于代理(解析含义作用) 二:正向代理 三:反向代理 四:项目应用场景 五:正向代理与反向代理区别 1.正向代理 2.反向代理 ...
- linux正则转换csv文件
- python习题_读写csv格式的文件
1.读写TXT文件 # *_* coding : UTF-8 *_* # 开发人员 : zfy # 开发时间 :2019/7/7 16:26 # 文件名 : lemon_10_file.PY # 开发 ...
- python3调用js的库之execjs
执行JS的类库:execjs,PyV8,selenium,node execjs是一个比较好用且容易上手的类库(支持py2,与py3),支持 JS runtime. 1.安装: pip install ...
- c++17 新特性
编译环境说明:gcc 8.1 + eclipse +windows 10 eclipse cpp默认支持c++14,做c++17开发时,需要手动进行配置. 1.关键字 1)constexpr c++1 ...
- bom案例4-模拟滚动条
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- cookie、session、jsession 关系
感谢大佬:https://www.cnblogs.com/fsjin/articles/3490531.html 在使用CAS的时候,对Cookies.session.jsession 这三者是什么不 ...
- js修改css
转载请注明来源:https://www.cnblogs.com/hookjc/ <style type="text/css"> .style{font-size:9pt ...
- 企业级Docker容器镜像仓库Harbor的搭建
Harbor简述 Habor是由VMWare公司开源的容器镜像仓库.事实上,Habor是在Docker Registry上进行了相应的企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:管理 ...
- 洛谷P1563 [NOIP2016 提高组] 玩具谜题
题目链接:https://www.luogu.com.cn/problem/P1563 哈哈哈,这个题拿来一读是不是很吃惊hahaha,我刚开始读的时候吓了我一跳,这么长的题干,这么绕的题意,还有下面 ...