【链接】h在这里写链接


【题意】


问你n个串里面有没有一个串,使得其余n-1个串都是他的子串。

【题解】


后缀数组.
答案肯定是那个最长的串。
则,把那个串求一下Sa数组(注意仅仅那个最长的串求)。
然后枚举其余n-1个子串。
看看它们是不是那个最长的串的子串;
(可以用一个类似二分的东西判断它是不是子串。);
(字符串比较,如果比当前后缀小,就往后缀小的地方,否则往大的地方,最后判断是不是子串。)
->利用Sa数组。
时间复杂度为O(n*logn)的样子。
感觉又解锁了新姿势。
(这里可以不用获取Height函数了)


【错的次数】


0

【反思】


主串的长度没那么长的时候,用这种方法的确合适。
hdu 2222那题。主串的长度太长了(1e6);
就显得没那么优秀了。

【代码】

#include<bits/stdc++.h>
using namespace std; const int N = 1e5;
const int SN = 2e2;
const int MAX_CHAR = 300;//每个数字的最大值。
int s[N + 10];//如果是数字,就写成int s[N+10]就好,从0开始存
int Sa[N + 10], T1[N + 10], T2[N + 10], C[N + 10], T;
int Height[N + 10], Rank[N + 10], idx[N + 10], in[N + 10], tag, L[N + 10], R[N + 10];
int Le[N + 10];
vector <string> vec;
bool flag[N + 10]; void build_Sa(int n, int m) {
int i, *x = T1, *y = T2;
for (i = 0; i<m; i++) C[i] = 0;
for (i = 0; i<n; i++) C[x[i] = s[i]]++;
for (i = 1; i<m; i++) C[i] += C[i - 1];
for (i = n - 1; i >= 0; i--) Sa[--C[x[i]]] = i;
for (int k = 1; k <= n; k <<= 1)
{
int p = 0;
for (i = n - k; i<n; i++) y[p++] = i;
for (i = 0; i<n; i++) if (Sa[i] >= k) y[p++] = Sa[i] - k;
for (i = 0; i<m; i++) C[i] = 0;
for (i = 0; i<n; i++) C[x[y[i]]]++;
for (i = 1; i<m; i++) C[i] += C[i - 1];
for (i = n - 1; i >= 0; i--) Sa[--C[x[y[i]]]] = y[i];
swap(x, y);
p = 1; x[Sa[0]] = 0;
for (i = 1; i<n; i++)
x[Sa[i]] = y[Sa[i - 1]] == y[Sa[i]] && y[Sa[i - 1] + k] == y[Sa[i] + k] ? p - 1 : p++;
if (p >= n) break;
m = p;
}
} bool contain(string &S, string T) {//最长的那个串和 短串
int l = 1, r = S.size(),temp = -1;
while (l <= r) {
int m = (l + r) >> 1;
if (S.compare(Sa[m], T.length(), T) <= 0)//如果后缀比S来的小。
{
temp = m;
l = m + 1;//可以再大一点
}
else
{
r = m - 1;
}
}
if (temp == -1)
return 0;
else
return S.compare(Sa[temp], T.length(), T) == 0;
} int main() {
//freopen("F:\\rush.txt", "r", stdin);
ios::sync_with_stdio(0), cin.tie(0);
int TT;
cin >> TT;
while (TT--) {
int T;
cin >> T;
int n = 0, ma = 0, idxma;
string ss;
vec.clear();
vec.push_back(" ");
for (int i = 1; i <= T; i++) {
cin >> ss;
vec.push_back(ss);
if ((int)ss.size() > ma) {
ma = (int)ss.size();
idxma = i;
}
}
for (int i = 0; i <= (int) vec[idxma].size() - 1; i++)
s[n++] = vec[idxma][i];
s[n] = 0;
build_Sa(n + 1, MAX_CHAR);//注意调用n+1
bool ok = true;
for (int i = 1; i <= T; i++)
if (idxma!=i){//不能是最大的那个,那个是要被匹配的。
if (!contain(vec[idxma], vec[i])) {
ok = false;
break;
}
}
if (ok) {
cout << vec[idxma] << endl;
}
else
cout << "No" << endl;
}
return 0;
}

【hdu 6208】The Dominator of Strings的更多相关文章

  1. 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题

    [HDU  3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...

  2. 【HDU 5647】DZY Loves Connecting(树DP)

    pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...

  3. -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】

    [把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...

  4. 【HDU 2196】 Computer(树的直径)

    [HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...

  5. 【HDU 2196】 Computer (树形DP)

    [HDU 2196] Computer 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 刘汝佳<算法竞赛入门经典>P282页留下了这个问题 ...

  6. 【HDU 5145】 NPY and girls(组合+莫队)

    pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Other ...

  7. 【hdu 2594】Simpsons’ Hidden Talents

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  8. 【hdu 1043】Eight

    [题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=1043 [题意] 会给你很多组数据; 让你输出这组数据到目标状态的具体步骤; [题解] 从12345 ...

  9. 【HDU 3068】 最长回文

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3068 [算法] Manacher算法求最长回文子串 [代码] #include<bits/s ...

随机推荐

  1. [BZOJ4184]shallot 线段树+线性基

    链接 题意:给你每个数字出现的时间和消失的时间,求每个时刻最大异或和 题解 按照时间建立线段树,线段树每个节点开个vector存一下这个时间区间有哪些数,然后递归进入的时候加入线性基,开一个栈记录一下 ...

  2. Sql Server 基础语法

    来自:http://www.cnblogs.com/AaronYang/archive/2012/04/24/2468093.html Sql Server 基础语法 -- 查看数据表 select  ...

  3. js深拷贝的实现方式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Spring_Learn

    IOC  控制反转,或者依赖注入  控制权的转移,应用程序本身不负责依赖对象的创建和维护.而是由外部容器负责创建和维护. DI(依赖注入)是其实现的一种方式 创建对象并且组装对象之间的关系. 1Spr ...

  5. 查看JSP和Servlet版本+

    如何查看JSP和Servlet版本 找到jsp-api.jar和servlet-api.jar ,分别打开META-INF下的MAINMEFT.MF文件,查看对应的版本. 例: JSP版本: Mani ...

  6. 网络流最大流dinic的板子

    void add(int u,int v,int w){ e[tot].v=v; e[tot].w=w; e[tot].nt=pre[u]; pre[u]=tot++; e[tot].v=u; e[t ...

  7. 【2017 Multi-University Training Contest - Team 3】Kanade's sum

    [Link]:http://acm.hdu.edu.cn/showproblem.php?pid=6058 [Description] 给你n个数; 它们是由(1..n)组成的排列; 然后给你一个数字 ...

  8. 怎样利用ash监控会话

    ash是很有效的监控工具之中的一个.1秒抓一次 select max(sample_time)over(),min(sample_time)over() from dba_hist_active_se ...

  9. 「微信小程序」有哪些冲击与机会?

    昨天晚上相信大家的朋友圈被「微信小程序」刷屏了,这影响力赶上了国务院出台新政策一样,足以说明微信在中国的影响力之大. 然后今天公号后台一大堆人问我怎么看这件事,不少人非常忧虑,仿佛自己将要失业一样. ...

  10. 编程算法 - 水洼的数量 代码(C)

    水洼的数量 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 有一个大小为N*M的园子, 雨后起了积水. 八连通的积水被觉得是连接在一起的. 请求 ...