Fleet of the Eternal Throne

Problem Description
> The Eternal Fleet was built many centuries ago before the time of Valkorion by an unknown race on the planet of Iokath. The fate of the Fleet's builders is unknown but their legacy would live on. Its first known action was in the annihilation of all life in Wild Space. It spread across Wild Space and conquered almost every inhabited world within the region, including Zakuul. They were finally defeated by a mysterious vessel known as the Gravestone, a massive alien warship that countered the Eternal Fleet's might. Outfitted with specialized weapons designed to take out multiple targets at once, the Gravestone destroyed whole sections of the fleet with a single shot. The Eternal Fleet was finally defeated over Zakuul, where it was deactivated and hidden away. The Gravestone landed in the swamps of Zakuul, where the crew scuttled it and hid it away.
>
> — Wookieepedia

The major defeat of the Eternal Fleet is the connected defensive network. Though being effective in defensing a large fleet, it finally led to a chain-reaction and was destroyed by the Gravestone. Therefore, when the next generation of Eternal Fleet is built, you are asked to check the risk of the chain reaction.

The battleships of the Eternal Fleet are placed on a 2D plane of n rows. Each row is an array of battleships. The type of a battleship is denoted by an English lowercase alphabet. In other words, each row can be treated as a string. Below lists a possible configuration of the Eternal Fleet.

aa
bbbaaa
abbaababa
abba

If in the x-th row and the y-th row, there exists a consecutive segment of battleships that looks identical in both rows (i.e., a common substring of the x-th row and y-th row), at the same time the substring is a prefix of any other row (can be the x-th or the y-th row), the Eternal Fleet will have a risk of causing chain reaction.

Given a query (x, y), you should find the longest substring that have a risk of causing chain reaction.

 
Input
The first line of the input contains an integer T, denoting the number of test cases.

For each test cases, the first line contains integer n (n≤105).

There are n lines following, each has a string consisting of lower case letters denoting the battleships in the row. The total length of the strings will not exceed 105.

And an integer m (1≤m≤100) is following, representing the number of queries.

For each of the following m lines, there are two integers x,y, denoting the query.

 
Output
You should output the answers for the queries, one integer per line.
 
Sample Input
1
3
aaa
baaa
caaa
2
2 3
1 2
Sample Output
3
3
 

题意:

  m只有100,

  先吧所有字符串用一个没有出现过的 id 串起来

  求一遍SA

  我们对于每个询问x,y,去二分答案mid

  对于后缀数组上 一段连续 的 值,如果最小值是大于 mid 的并且 包含了x,y串里的 字串, 并且还包含了 任意 给定母串的 前缀 ,那么就是可行的 Mid

  上面的check可以O(n)

#include<bits/stdc++.h>
using namespace std;
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
typedef unsigned long long ULL;
const long long INF = 1e18+1LL;
const double pi = acos(-1.0); const int N = 6e5+,M=1e6+,inf=; int *ran,r[N],sa[N],height[N],wa[N],wb[N],wm[N];
bool cmp(int *r,int a,int b,int l) {
return r[a] == r[b] && r[a+l] == r[b+l];
}
void SA(int *r,int *sa,int n,int m) {
int *x=wa,*y=wb,*t;
for(int i=;i<m;++i)wm[i]=;
for(int i=;i<n;++i)wm[x[i]=r[i]]++;
for(int i=;i<m;++i)wm[i]+=wm[i-];
for(int i=n-;i>=;--i)sa[--wm[x[i]]]=i;
for(int i=,j=,p=;p<n;j=j*,m=p){
for(p=,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)wm[i]=;
for(i=;i<n;++i)wm[x[y[i]]]++;
for(i=;i<m;++i)wm[i]+=wm[i-];
for(i=n-;i>=;--i)sa[--wm[x[y[i]]]]=y[i];
for(t=x,x=y,y=t,i=p=,x[sa[]]=;i<n;++i) {
x[sa[i]]=cmp(y,sa[i],sa[i-],j)?p-:p++;
}
}
ran=x;
}
void Height(int *r,int *sa,int n) {
for(int i=,j=,k=;i<n;height[ran[i++]]=k)
for(k?--k:,j=sa[ran[i]-];r[i+k] == r[j+k];++k);
} int vis[N],n,id[N],first[N];
int check(int x,int y,int len) {
int i = ,cnt = ,flag,fi = ;
while() {
while(i <= n && height[i] < len) i++;
if(i > n) return ;
vis[x] = ,vis[y] = ;fi = ; flag = id[sa[i-]];
fi = first[sa[i-]];
vis[flag] = ;
// if(len == 3) cout<<flag<<endl;
while(i <= n && height[i] >= len) {
vis[id[sa[i]]] = ;
// if(len == 3) cout<<id[sa[i]]<<endl;
fi |= first[sa[i]];
i++;
}
if(vis[x] && vis[y] && fi) return ;
}
return ;
} int m;
string a[N];
int main() {
int T;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
memset(first,,sizeof(first));
memset(vis,,sizeof(vis));
int cnt = ,san = ;
for(int i = ; i <= n; ++i) {
cin>>a[i];
int len = a[i].length();
for(int j = ; j < len; ++j) {
r[cnt++] = a[i][j] - 'a' + ;
id[cnt-] = i;
if(j == )
first[cnt-] = ;
}
id[cnt] = i;
r[cnt++] = san++;
}
r[--cnt] = ;
n = cnt;
SA(r,sa,n+,san+);
Height(r,sa,n);
scanf("%d",&m);
while(m--) {
int x,y;
scanf("%d%d",&x,&y);
int l = ,r = min(a[x].length(),a[y].length()),ans = ;
while(l <= r) {
int md = (l + r)>>;
if(check(x,y,md)) ans = md,l = md+;
else r = md - ;
}
printf("%d\n",ans);
}
}
return ;
}

HDU 6138 Fleet of the Eternal Throne 后缀数组 + 二分的更多相关文章

  1. HDU 6138 Fleet of the Eternal Throne(后缀自动机)

    题意 题目链接 Sol 真是狗血,被疯狂卡常的原因竟是 我们考虑暴力枚举每个串的前缀,看他能在\(x, y\)的后缀自动机中走多少步,对两者取个min即可 复杂度\(O(T 10^5 M)\)(好假啊 ...

  2. 2017ACM暑期多校联合训练 - Team 8 1006 HDU 6138 Fleet of the Eternal Throne (字符串处理 AC自动机)

    题目链接 Problem Description The Eternal Fleet was built many centuries ago before the time of Valkorion ...

  3. HDU 6138 Fleet of the Eternal Throne(AC自动机)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6138 [题目大意] 给出一些串,询问第x个串和第y个串的公共子串, 同时要求该公共子串为某个串的前 ...

  4. 2017多校第8场 HDU 6138 Fleet of the Eternal Throne AC自动机或者KMP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6138 题意:给n个串,每次询问x号串和y号串的最长公共子串的长度,这个子串必须是n个串中某个串的前缀 ...

  5. 2017多校第8场 HDU 6138 Fleet of the Eternal Throne 思维,暴力

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6138 题意:给了初始区间[-1,1],然后有一些操作,可以r加上一个数,l减掉一个数,或者同时操作,问 ...

  6. BZOJ 3230: 相似子串( RMQ + 后缀数组 + 二分 )

    二分查找求出k大串, 然后正反做后缀数组, RMQ求LCP, 时间复杂度O(NlogN+logN) -------------------------------------------------- ...

  7. BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案

    BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单 ...

  8. 【bzoj4310】跳蚤 后缀数组+二分

    题目描述 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典序最大的那一个 ...

  9. BZOJ 1717 [USACO06DEC] Milk Patterns (后缀数组+二分)

    题目大意:求可重叠的相同子串数量至少是K的子串最长长度 洛谷传送门 依然是后缀数组+二分,先用后缀数组处理出height 每次二分出一个长度x,然后去验证,在排序的后缀串集合里,有没有连续数量多于K个 ...

随机推荐

  1. iOS学习笔记06-手势识别

    一.UIGestureRecognizer简单介绍 我们已经学习了触摸事件处理,但触摸事件处理起来很麻烦,每个触摸事件处理都需要实现3个touches方法,比较繁琐,实际上我们可以使用更加简单的触摸事 ...

  2. [POJ1143]Number Game

    [POJ1143]Number Game 试题描述 Christine and Matt are playing an exciting game they just invented: the Nu ...

  3. Uva5009 Error Curves

    已知n条二次曲线si(x) = ai*x^2 + bi*x + ci(ai ≥ 0),定义F(x) = max{si(x)},求出F(x)在[0,1000]上的最小值. 链接:传送门 分析:最大值最小 ...

  4. 【2018.11.22】CTSC2018(模拟赛!)

    太蠢了……$noip$ 后第一次模拟赛竟然是这样的……完全就是打击自信 / 降智…… 1. 假面 一道神仙概率 $dp$!第一次写…… 拿到题就发现血量 $m_i$ 的上限只有 $100$! 然后 $ ...

  5. 理解 Nova 架构

    Compute Service Nova 是 OpenStack 最核心的服务,负责维护和管理云环境的计算资源. OpenStack 作为 IaaS 的云操作系统,虚拟机生命周期管理也就是通过 Nov ...

  6. Codeforces Round #287 (Div. 2) E. Breaking Good [Dijkstra 最短路 优先队列]

    传送门 E. Breaking Good time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  7. noip 2013 luogu P1969 积木大赛

    题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前,没有任何积木(可以看成 ...

  8. Hadoop HDFS 常用命名

    HDFS命令基本格式:hadoop fs -cmd < args > ls 命令hadoop fs -ls / 列出hdfs文件系统根目录下的目录和文件 hadoop fs -ls -R ...

  9. 9.Java web—JSP内置对象

    容器内置了9大对象,这些对象在jsp页无需实例化,可以直接使用. 分别为request. response .session. application .out. pageContext .confi ...

  10. java判断字符串中是否含有汉字

    原文:http://www.open-open.com/code/view/1426332240717 判断字符串中是否含有汉字: String str = "test中文汉字"; ...