spoj220
题解:
后缀数组
把所有串连接起来
二分答案
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
const int N=;
typedef long long ll;
using namespace std;
char ch[N];
int str[N],l[N],mx[N],mn[N],in[N],k,wa[N],wb[N],wv[N],Ws[N],sa[N],Rank[N],height[N];
int cmp(int *r,int a,int b,int l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void da(const int *r,int *sa,int n,int m)
{
int *x=wa,*y=wb;
for (int i=;i<m;i++) Ws[i]=;
for (int i=;i<n;i++) Ws[x[i]=r[i]]++;
for (int i=;i<m;i++) Ws[i]+=Ws[i-];
for (int i=n-;i>=;i--) sa[--Ws[x[i]]]=i;
for (int j=,p=;p<n;j*=,m=p)
{
p=;
for (int i=n-j;i<n;i++) y[p++]=i;
for (int i=;i<n;i++)
if (sa[i]>=j) y[p++]=sa[i]-j;
for (int i=;i<n;i++) wv[i]=x[y[i]];
for (int i=;i<m;i++) Ws[i]=;
for (int i=;i<n;i++) Ws[wv[i]]++;
for (int i=;i<m;i++) Ws[i]+=Ws[i-];
for (int i=n-;i>=;i--) sa[--Ws[wv[i]]]=y[i];
swap(x,y);p=;x[sa[]]=;
for (int i=;i<n;i++)x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
}
void calheight(const int *r,int *sa,int n)
{
int j,k=;
for (int i=;i<=n;i++) Rank[sa[i]]=i;
for (int i=;i<n;height[Rank[i++]]=k)
for (k?k--:,j=sa[Rank[i]-];r[i+k]==r[j+k];k++);
}
int pd(int mid,int n)
{
for (int i=;i<k;i++){mx[i]=;mn[i]=1e9;}
for (int i=;i<=n;i++)
{
if (height[i]<mid)
{
for (int j=;j<k;j++)
{
mx[j]=;
mn[j]=1e9;
}
mx[in[sa[i]]]=sa[i];
mn[in[sa[i]]]=sa[i];
}
else
{
mx[in[sa[i]]]=max(mx[in[sa[i]]],sa[i]);
mn[in[sa[i]]]=min(mn[in[sa[i]]],sa[i]);
mx[in[sa[i-]]]=max(mx[in[sa[i-]]],sa[i-]);
mn[in[sa[i-]]]=min(mn[in[sa[i-]]],sa[i-]);
int j;
for (j=;j<k;j++)
if (mx[j]-mn[j]<mid)break;
if (j==k) return ;
}
}
return ;
}
int main()
{
int cnt=,t;
scanf("%d",&t);
while (t--)
{
scanf("%d",&k);
int n=;
for (int i=;i<k;i++)
{
scanf("%s",ch);
l[i]=strlen(ch);
for (int j=n;j<n+l[i];j++)
{
str[j]=ch[j-n]-'a'+;
in[j]=i;
}
n+=l[i]+;
str[n-]=+i;
}
n--;
str[n]=;
da(str,sa,n+,+k+);
calheight(str,sa,n);
int l=,r=;
while (l<r)
{
int mid=(l+r+)/;
if (pd(mid,n))l=mid;
else r=mid-;
}
printf("%d\n",l);
}
return ;
}
spoj220的更多相关文章
- 【SPOJ220】Relevant Phrases of Annihilation(后缀数组,二分)
题意: n<=10,len<=1e4 思路: #include<cstdio> #include<cstring> #include<string> # ...
- SPOJ220 Relevant Phrases of Annihilation(后缀数组)
引用罗穗骞论文中的话: 先将n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组.然后二分答案,再将后缀分组.判断的时候,要看是否有一组后缀在每个原来的字符串中至少出现两次,并 ...
- SPOJ220 Relevant Phrases of Annihilation
http://www.spoj.com/problems/PHRASES/ 题意:给n个串,求n个串里面都有2个不重叠的最长的字串长度. 思路:二分答案,然后就可以嘿嘿嘿 PS:辣鸡题目毁我青春,一开 ...
- 2018.11.30 spoj220 Relevant Phrases of Annihilation(后缀数组+二分答案)
传送门 代码: 先用特殊字符把所有字符串连接在一起. 然后二分答案将sasasa数组分组. 讨论是否存在一个组满足组内对于每一个字符串都存在两段不相交字串满足条件. #include<bits/ ...
- 【SPOJ220】Relevant Phrases of Annihilation (SA)
成功完成3连T! 嗯没错,三道TLE简直爽到不行,于是滚去看是不是模版出问题了..拿了3份其他P党的模版扔上去,嗯继续TLE...蒟蒻表示无能为力了... 思路像论文里面说的,依旧二分长度然后分组 ...
- 【距离GDOI:131天】 后缀数组完毕
用了近两周的时间,终于把罗神那篇后缀数组应用看完了,题目也写了一遍,T了无数次...详见前几篇博文... 后缀数组很重要的是那个height数组,可以用来做各种奇奇怪怪的东西...常用方法去是去二分, ...
- String Algorithm Summary - 1
目录 Suffix Array Summay 单个字符串问题 两个字符串问题 多个字符串问题 AC-Automaton Summary 求长度为n(2e9)不包含给定字符串的合法串个数 包含至少一个词 ...
随机推荐
- SQL service 中的 ”输入SQL命令窗口“ 打开了 “属性界面” 回到 ”输入SQL命令窗口“
输入SQL命令窗口点击上面的菜单栏中的 “窗口”
- C#中的var
var关键字是C#3.0开始新增的特性,称为推断类型(其实也就是弱化类型的定义). var a =23: 则a是整型,var a = “lgs”:则a是字符型,但使用Var类型要注意: 1.必须在定义 ...
- zabbix自定义监控方式
- spring集成JMS访问ActiveMQ
首先我们搭建一个spring-mvc项目,项目可以参考:spring-mvc 学习笔记 步骤: 在pom.xml中加上需要的包 修改web.xml,增加IOC容器 spring配置文件applicat ...
- 亚马逊商品页面的简单爬取 --Pyhon网络爬虫与信息获取
1.亚马逊商品页面链接地址(本次要爬取的页面url) https://www.amazon.cn/dp/B07BSLQ65P/ 2.代码部分 import requestsurl = "ht ...
- 浅谈微服务架构、容器技术与K8S
关注嘉为科技,获取运维新知 企业应用系统:从单体应用走向微服务架构:从裸金属走向容器. 如果在诸多热门云计算技术诸如容器.微服务.DevOps.OpenStack等之中,找出一个最火的方向,那么可能非 ...
- 快速幂的求解-java方法(int范围之内)
思想就是,将十进制数化成二进制数.其它就是很简单了. 如:2的11次幂,11的二进制位1011,所以2(11) = 2(2(0) + 2(1) + 2(3)); 具体实现步骤,看代码比较简单 impo ...
- PHP设计模式注意点
PHP命名空间 可以更好地组织代码,与Java中的包类似. Test1.php <?php namespace Test1;//命名空间Test1 function test(){ echo _ ...
- 【其他】【服务器】【4】删除Windows系统中不想要的服务
步骤: 1,开始菜单栏查找“服务”,打开后找到想要删除的服务 2,右键单击想要删除的服务,选择“属性”-“常规”-“服务名称”,记下服务名称(AA) 3,开始菜单栏输入“cmd”打开命令行窗口,输入s ...
- introsort(内省排序)
本文转载于:https://blog.csdn.net/sky453589103/article/details/51116264 快速排序是一种很快的算法,它平均的时间复杂度WieO(nlgn), ...