uva11107 后缀数组
题意给了n个串 然后计算 这些串中的子串在大于1/2的串中出现 求出这个串的最长长度。 将这些串用一个每出现的不同的字符拼起来 ,然后二分找lcp
#include <iostream>
#include <algorithm>
#include <string.h>
#include <algorithm>
#include <vector>
#include <cstdio>
using namespace std;
const int maxn=;
const int maxm=;
const int MM=maxn*maxm;
struct SuffixArray
{
int s[MM]; // 原始字符数组(最后一个字符应必须是0,而前面的字符必须非0)
int sa[MM]; // 后缀数组
int rank[MM]; // 名次数组. rank[0]一定是n-1,即最后一个字符
int height[MM]; // height数组
int t[MM], t2[MM], c[MM]; // 辅助数组
int n; // 字符个数
void clear(){ n=; }
void build(int m)
{
int *x=t,*y=t2,i;
for(i=; i<m; i++)c[i]=;
for(i=; i<n; i++)c[ x[i] = s[i] ]++;
for(i=; i<m; i++)c[ i ] += c[ i- ];
for(i = n-; i >= ; i--) sa[--c[x[i]]] = i;
for(int k=; k<=n; k<<=)
{
int p=;
for(i=n-k; i<n; i++)y[p++]=i;
for(i=; i<n; i++)if(sa[i]>=k)y[p++]=sa[i]-k;
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( i=; i<n; i++) x[ sa[i] ]= y[ sa[i] ]==y[sa[i-]] && y[ sa[i]+k ]== y[ sa[i-] +k ]?p-:p++;
if(p>=n)break;
m=p;
}
}
void build_height() {
int i, k = ;
for(i = ; i < n; i++) rank[sa[i]] = i;
height[]=;
for(i = ; i < n; i++) {
if(k) k--;
if(rank[i]==)continue;
int j = sa[rank[i]-];
while(i+k<n&&j+k<n&&s[i+k] == s[j+k]) k++;
height[rank[i]] = k;
}
}
}sa;
char word[MM];
int idx[MM],n,maxlen;
int flag[];
void add(int ch, int i)
{
idx[sa.n] = i;
sa.s[sa.n++] = ch;
}
// 子串[L,R) 是否符合要求
bool good(int L, int R,int &ss)
{ if(R - L <= n/) return false;
int cnt = ;
for(int i = L; i < R; i++) {
int x = idx[sa.sa[i]];
if(x != n && flag[x]!=ss) { flag[x] = ss; cnt++; }
}
return cnt > n/;
} void print_sub(int L, int R)
{
for(int i = L; i < R; i++)
printf("%c", sa.s[i] - + 'a');
printf("\n");
}
int ss;
bool print_solutions(int len, bool print)
{
int L = ;
ss++;
for(int R = ; R <= sa.n; R++) {
if(R == sa.n || sa.height[R] < len) { // 新开一段
if(good(L, R,ss)) {
if(print) print_sub(sa.sa[L], sa.sa[L] + len); else return true;
}
ss++;
L = R;
}
}
return false;
} void solve(int maxlen)
{
if(!print_solutions(, false))
printf("?\n");
else {
int L = , R = maxlen, M;
while(L < R) {
M = L + (R-L+)/;
if(print_solutions(M, false)) L = M;
else R = M-;
}
print_solutions(L, true);
}
} int main()
{
int kase=;
while(scanf("%d",&n)==)
{
if(n==)break;
if(kase++>) puts("");
maxlen=;
sa.clear();
for(int i=; i<n; i++)
{
scanf("%s",word);
int sz= strlen(word);
maxlen=max(sz,maxlen);
for(int j=; j<sz; j++)
{
add(word[j]-'a'+,i);
}
add(+i,n);
}
add(+n,n);
if(n==)printf("%s\n",word);
else
{
ss=;
memset(flag,,sizeof(flag));
sa.build( +n+ );
sa.build_height();
solve(maxlen);
}
}
return ;
}
uva11107 后缀数组的更多相关文章
- UVA11107 Life Forms --- 后缀数组
UVA11107 Life Forms 题目描述: 求出出现在一半以上的字符串内的最长字符串. 数据范围: \(\sum len(string) <= 10^{5}\) 非常坑的题目. 思路非常 ...
- uva11107(后缀数组)
uva11107 题意 输入 n 个 DNA 序列,求出长度最大的字符串,使得它在超过一半的 DNA 序列中连续出现.如果有多解,按字典序输出. 分析 论文 后缀数组经典题.加深几个关键数组的印象. ...
- 【UVA11107 训练指南】Life Forms【后缀数组】
题意 输入n(n<=100)个字符串,每个字符串长度<=1000,你的任务是找出一个最长的字符串使得超过一半的字符串都包含这个字符串. 分析 训练指南上后缀数组的一道例题,据说很经典(估计 ...
- 后缀数组的倍增算法(Prefix Doubling)
后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]
1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1383 Solved: 582[Submit][St ...
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- POJ1743 Musical Theme [后缀数组]
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ...
- 后缀数组(suffix array)详解
写在前面 在字符串处理当中,后缀树和后缀数组都是非常有力的工具. 其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料. 其实后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现, ...
随机推荐
- java中调用操作系统的命令
java.lang.Runtime类提供了exec() 方法来执行操作系统的命令. 使用静态的Runtime.getRuntime()方法可以获得当前的java应用程序对应的Runtime类的实例 R ...
- python类中的self参数和cls参数
1. self表示一个类的实例对象本身.如果用了staticmethod就无视这个self了,就将这个方法当成一个普通的函数使用了. 2. cls表是这个类本身. # 代码为证 class A(obj ...
- DevOps之零停机部署
“零停机部署(ZDD)可在不中断现有服务的情况下部署新版系统.” 通过ZDD方式部署应用程序时,可在确保用户不会遭遇应用程序停机的前提下将新版应用引入生产环境.从用户和公司的角度来看,这应该是最佳部署 ...
- html 在一个超链接上面,鼠标移动上去时,也显示一串文字,如何实现
a标签的title属性,对title属性赋值即可.例如:<a href="http://www.baidu.com/" title="跳转到百度"> ...
- Java-字符串加密
1设计思想: 改程序是对小写的a到z进行加密,输入一段字符串str,输入加密的密匙k,判断录入的的字符与 ‘z’-k+1的大小,比其小的直接加上密匙转化为新的字符,大于的加(k-26)将最后几位字符转 ...
- POJ 1700 - Crossing River
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 13982 Accepted: 5349 Description A gr ...
- 修改机器名、IP对arcgis server、portal的影响?
修改机器名.IP是否对ArcGIS Server .Portal等有影响? 请教赛姐:修改IP对ArcGIS Server .Portal 无影响,不过建议将ArcGIS Server .Portal ...
- GP服务中无Tasks
发布GP服务,之后执行GP服务时,发现无Tasks,如下图所示 正常情况应该如下图 问题原因在于,arcmap与server版本不一致~~ (10.4.1arcmap 与 10.2.2 server) ...
- 机器学习【算法】:KNN近邻
引言 本文讨论的kNN算法是监督学习中分类方法的一种.所谓监督学习与非监督学习,是指训练数据是否有标注类别,若有则为监督学习,若否则为非监督学习.监督学习是根据输入数据(训练数据)学习一个模型,能对后 ...
- CF45G Prime Problem 构造+数论
正解:构造+数论 解题报告: 传送门! maya这题好神仙啊我jio得,,,反正我当初听的时候是没有太懂的,,, 首先这题你要知道一些必要的数学姿势 比如哥德巴赫猜想巴拉巴拉的 然后直接讲题趴QAQ ...