题目链接:

  Poj 3294 Life Forms

题目描述:

  有n个文本串,问在一半以上的文本串出现过的最长连续子串?

解题思路:

  可以把文本串用没有出现过的不同字符连起来,然后求新文本串的height。然后二分答案串的长度K,根据K把新文本串的后缀串分块,统计每块中的原文本串出现的次数,大于原文本串数目的一半就作为答案记录下来,对于输出字典序,height就是排好序的后缀数组,只要按照顺序输出即可。

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = ; int sa[maxn], rank[maxn], height[maxn], vis[], res[maxn];
int t1[maxn], t2[maxn], r[maxn], flag[maxn], c[maxn]; bool cmp (int *str, int a, int b, int k)
{
return str[a]==str[b] && str[a+k]==str[b+k];
} void da (int *str, int n, int m)
{
n ++;
int *x = t1, *y = t2, i, j; for (i=; i<m; i++) c[i] = ;
for (i=; i<n; i++) c[x[i]=str[i]] ++;
for (i=; i<m; i++) c[i] += c[i-];
for (i=n-; i>=; i--) sa[-- c[x[i]]] = i; for (j=; j<=n; j*=)
{
int p = ;
for (i=n-j; i<n; i++) y[p++] = i;
for (i=; i<n; i++) if (sa[i] >= j) y[p++] = sa[i] - j; for (i=; i<m; i++) c[i] = ;
for (i=; i<n; i++) c[x[y[i]]] ++;
for (i=; i<m; i++) c[i] += c[i-];
for (i=n-; i>=; i--) sa[-- c[x[y[i]]]] = y[i]; swap (x, y);
p = ;
x[sa[]] = ;
for (int i=; i<n; i++)//i是rank
x[sa[i]] = cmp(y, sa[i-], sa[i], j)?p-:p++;
if (p >= n)
break;
m = p;
} for (i=; i<n; i++)
rank[sa[i]] = i; int k = ;
n --;
for (int i=; i<n; i++)
{
if (k) k --;
int j = sa[rank[i] - ];
while (str[i+k] == str[j+k]) k++;
height[rank[i]] = k;
}
} bool Bin_sreach (int x, int k, int n)
{
int ans, num;
ans = num = ;
memset (vis, , sizeof(vis)); for (int i=; i<=k; i++)
{
if (height[i] >= x)
{
ans += vis[flag[sa[i-]]]?:;
vis[flag[sa[i-]]] = ; ans += vis[flag[sa[i]]]?:;
vis[flag[sa[i]]] = ;
}
else
{
if (ans* > n)
res[++ num] = sa[i-]; ans = ;
memset (vis, , sizeof(vis));
}
}
if (ans* > n)
res[++ num] = sa[k-]; if (num)
{
res[] = num;
return true;
}
return false;
} int main ()
{
int n, l = ;
char str[];
while (scanf ("%d", &n), n)
{
if (l ++)
printf ("\n"); int k = ;
for (int i=; i<n; i++)
{
scanf ("%s", str);
for (int j=; str[j]; j++)
{
r[k] = str[j];
flag[k++] = i;//记录k字母所在的字符串
}
r[k] = + i;
flag[k++] = -;
} r[k] = ;
da (r, k, ); int low = , high = k, mid, ans = ;
while (low <= high)
{//二分枚举
mid = (low + high) / ;
if (Bin_sreach(mid, k, n))
{
ans = mid;
low = mid + ;
}
else
high = mid - ;
} if (low == )
{
printf ("?\n");
continue;
} for (int i=; i<=res[]; i++)
{
for (int j=res[i]; j<res[i]+ans; j ++)
printf ("%c", r[j]);
printf ("\n");
}
}
return ;
}

Poj 3294 Life Forms (后缀数组 + 二分 + Hash)的更多相关文章

  1. poj 3294 Life Forms - 后缀数组 - 二分答案

    题目传送门 传送门I 传送门II 题目大意 给定$n$个串,询问所有出现在严格大于$\frac{n}{2}$个串的最长串.不存在输出'?' 用奇怪的字符把它们连接起来.然后求sa,hei,二分答案,按 ...

  2. POJ 3294 Life Forms 后缀数组+二分 求至少k个字符串中包含的最长子串

    Life Forms   Description You may have wondered why most extraterrestrial life forms resemble humans, ...

  3. Poj 1743 Musical Theme(后缀数组+二分答案)

    Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...

  4. [poj 1743] Musical Theme 后缀数组 or hash

    Musical Theme 题意 给出n个1-88组成的音符,让找出一个最长的连续子序列,满足以下条件: 长度大于5 不重叠的出现两次(这里的出现可以经过变调,即这个序列的每个数字全都加上一个整数x) ...

  5. Poj 3261 Milk Patterns(后缀数组+二分答案)

    Milk Patterns Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk g ...

  6. POJ 1226 Substrings(后缀数组+二分答案)

    [题目链接] http://poj.org/problem?id=1226 [题目大意] 求在每个给出字符串中出现的最长子串的长度,字符串在出现的时候可以是倒置的. [题解] 我们将每个字符串倒置,用 ...

  7. BZOJ 4278: [ONTAK2015]Tasowanie (后缀数组 / 二分+hash)

    直接归并,然后如果哪边的后缀字典序比较小就去哪边,然后就可以后缀数组 博客传送门- 但是本蒟蒻不会后缀数组 Upd:Upd:Upd:现在会了233.一道差不多的题:BZOJ 1692: [Usaco2 ...

  8. BZOJ 1692: [Usaco2007 Dec]队列变换 (后缀数组/二分+Hash)

    跟BZOJ 4278: [ONTAK2015]Tasowanie一模一样 SA的做法就是把原串倒过来接在原串后面,O(nlogn)O(nlogn)O(nlogn)做后缀数组,就能O(1)O(1)O(1 ...

  9. POJ3294--Life Forms 后缀数组+二分答案 大于k个字符串的最长公共子串

                                                                              Life Forms Time Limit: 500 ...

随机推荐

  1. 火狐浏览器Firefox 如何使用iMacros 自动填写网页表单

    1 我们首先访问一个想要自动填写表单的网站.我们以百度为例,右侧有登录窗口.   2 然后我们点开刚安装上的iMacros插件,一般安装之后就会自动出现在浏览器的某个地方,点击记录选项卡,再点击记录. ...

  2. Atitit.软件仪表盘(7)--温度监測子系统--电脑重要部件温度与监控and警报

    Atitit.软件仪表盘(7)--温度监測子系统--电脑重要部件温度与监控and警报 Cpu温度.风扇转速 主板温度 显卡温度 硬盘温度 电池温度 鲁大师  硬盘温度 Cpu温度  core temp ...

  3. js性能优化之函数节流(分流函数)

    函数节流的原理 比如我们在window.onresize事件中要打印当前浏览器窗口的大小,在我们通过拖拽来改变窗口大小时候,打印窗口大小这个工作1s就运行了10次.而实际上我们只需要2次或者3次. 比 ...

  4. SQLite Expert表分离和解决SQLite Expert删除表后大小不变的问题

    最后要使用到号码归属地的查询,在网上找到一个数据库文件.大小有12M多,压缩成zip也有1.9M,这样对于一个apk的大小非常不利,后来看了一下数据库的内容,发现有非常多冗余.特别是中文字符占用非常大 ...

  5. #define中的#和##作用

    #define语句中的#是把参数字符串化,##是连接两个参数成为一个整体. #define FACTORY_REF(name) { #name, Make##name } 中#name就是将传入的na ...

  6. Hybrid App适配Android注意点

    近期把做好的ipad HTML5混合应用适配到android上,发现android的webview比 iPad差太多了,android4.4因为升级到chromium.和chrome内核一致,全部问题 ...

  7. SQL yog过期后教你怎么让他不过期

    打开注册表  安装sqlyog后,进入注册表编辑器,进入\HEYK_CURRENT_USER\Software\,找到以{}括起来的那项直接干掉! 1, regedit 2,修改 3,

  8. js实现的美女瀑布流效果代码

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  9. LoadRunner中存储表格参数------关联数组

    主要用到 web_reg_save_param_ex函数("Scope=All",), sprintf( CProdNo,"{CProdNo_%d}",i ); ...

  10. iOS 开发者中的个人账号与组织账号之间区别

    苹果对开发者主要分为3类:个人.组织(公司.企业).教育机构.即: 1.个人(Individual) 2.组织(Organizations) 组织类又分为2个小类: (1)公司(Company) (2 ...