SPOJ - PHRASES
题意:
给n个字符串,求出最长的子串。使得子串在每个字符串中不重叠地至少出现2次。输出子串长度。
题解:
用后缀数组求出height数组,之后二分答案。check时对height数组进行分组,并维护每个字符串的最前和最后位置。
- #include <bits/stdc++.h>
- using namespace std;
- const int N = 1e5+;
- int t, n, k, len;
- int vis[N], val[][];
- char s[N];
- int r[N];
- int sa[N], t1[N], t2[N], c[N], height[N], rank[N];
- void SA(int *r, int n, int m) {
- int *x = t1, *y = t2;
- for(int i = ; i < m; i++) c[i] = ;
- for(int i = ; i < n; i++) c[x[i] = r[i]]++;
- for(int i = ; i < m; i++) c[i] += c[i-];
- for(int i = n-; i >= ; i--) sa[--c[x[i]]] = i;
- for(int k = ; k <= n; k <<= ) {
- int p = ;
- for(int i = n-k; i < n; i++) y[p++] = i;
- for(int i = ; i < n; i++) if(sa[i] >= k) y[p++] = sa[i]-k;
- for(int i = ; i < m; i++) c[i] = ;
- for(int i = ; i < n; i++) c[x[y[i]]]++;
- for(int i = ; i < m; i++) c[i] += c[i-];
- for(int i = n-; i >= ; i--) sa[--c[x[y[i]]]] = y[i];
- swap(x, y);
- p = ; x[sa[]] = ;
- for(int 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;
- }
- int k = , j;
- 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 add(int x, int v) {
- int p = vis[sa[x]], c = ;
- if(val[p][] == - && val[p][] == -) {
- val[p][] = val[p][] = sa[x];
- c++;
- }
- else {
- if(sa[x] < val[p][]) {
- if(val[p][] - val[p][] < v && val[p][] - sa[x] >= v) c++;
- val[p][] = sa[x];
- }
- else if(sa[x] > val[p][]) {
- if(val[p][] - val[p][] < v && sa[x] - val[p][] >= v) c++;
- val[p][] = sa[x];
- }
- }
- return c;
- }
- bool check(int x) {
- int cnt = ;
- int l = n;
- while(l < len) {
- if(height[l] < x) {
- memset(val, -, sizeof(val));
- cnt = ;
- cnt += add(l, x);
- }
- else cnt += add(l, x);
- l++;
- if(cnt == *n) return true;
- }
- return false;
- }
- int main() {
- scanf("%d", &t);
- while(t--) {
- len = ;
- scanf("%d", &n);
- memset(vis, , sizeof(vis));
- for(int i = ; i <= n; i++) {
- scanf("%s", s);
- k = strlen(s);
- for(int j = ; j < k; j++) r[len++] = s[j]-'a'+;
- vis[len] = ;
- r[len++] = i;
- }
- for(int i = ; i < len; i++) vis[i] += vis[i-];
- SA(r, len, );
- int l = , r = 1e5;
- while(l <= r) {
- int mid = l+r>>;
- if(check(mid)) l = mid+;
- else r = mid-;
- }
- printf("%d\n", r);
- }
- }
SPOJ - PHRASES的更多相关文章
- SPOJ PHRASES 每个字符串至少出现两次且不重叠的最长子串
Description You are the King of Byteland. Your agents have just intercepted a batch of encrypted ene ...
- POJ - 3294~Relevant Phrases of Annihilation SPOJ - PHRASES~Substrings POJ - 1226~POJ - 3450 ~ POJ - 3080 (后缀数组求解多个串的公共字串问题)
多个字符串的相关问题 这类问题的一个常用做法是,先将所有的字符串连接起来, 然后求后缀数组 和 height 数组,再利用 height 数组进行求解. 这中间可能需要二分答案. POJ - 3294 ...
- SPOJ - PHRASES Relevant Phrases of Annihilation
传送门:SPOJ - PHRASES(后缀数组+二分) 题意:给你n个字符串,找出一个最长的子串,他必须在每次字符串中都出现至少两次. 题解:被自己蠢哭...记录一下自己憨憨的操作,还一度质疑评测鸡( ...
- SPOJ PHRASES 后缀数组
题目链接:http://www.spoj.com/problems/PHRASES/en/ 题意:给定n个字符串,求一个最长的子串至少在每个串中的不重叠出现次数都不小于2.输出满足条件的最长子串长度 ...
- SPOJ - PHRASES K - Relevant Phrases of Annihilation
K - Relevant Phrases of Annihilation 题目大意:给你 n 个串,问你最长的在每个字符串中出现两次且不重叠的子串的长度. 思路:二分长度,然后将height分块,看是 ...
- SPOJ - PHRASES Relevant Phrases of Annihilation —— 后缀数组 出现于所有字符串中两次且不重叠的最长公共子串
题目链接:https://vjudge.net/problem/SPOJ-PHRASES PHRASES - Relevant Phrases of Annihilation no tags You ...
- SPOJ - PHRASES Relevant Phrases of Annihilation (后缀数组)
You are the King of Byteland. Your agents have just intercepted a batch of encrypted enemy messages ...
- SPOJ PHRASES Relevant Phrases of Annihilation(后缀数组 + 二分)题解
题意: 给\(n\)个串,要你求出一个最长子串\(A\),\(A\)在每个字串至少都出现\(2\)次且不覆盖,问\(A\)最长长度是多少 思路: 后缀数组处理完之后,二分这个长度,可以\(O(n)\) ...
- KUANGBIN带你飞
KUANGBIN带你飞 全专题整理 https://www.cnblogs.com/slzk/articles/7402292.html 专题一 简单搜索 POJ 1321 棋盘问题 //201 ...
随机推荐
- java nio之Buffer
一.JAVA NIO 是在和channel交互的时候使用的.Channel将数据读入缓冲区,然后我们又从缓冲区访问数据.写数据时,首先将要发送的数据按顺序填入缓冲区.基本上,缓冲区只是一个列表,它的所 ...
- js实现无限级分类
let arr = [ {id:1,name:"php",pid:0}, {id:2,name:"php基础",pid:1}, {id:3,name:" ...
- web项目优化
1 循环时没有使用break 案例:查找一个值是否在数组中存在(为举例舍弃自带函数) $aa=123; $arr=array(234,123,5,6,45646,346,23); foreach($ ...
- Spark mlib的本地向量
Spark mlib的本地向量有两种: DenseVctor :稠密向量 其创建方式 Vector.dense(数据) SparseVector :稀疏向量 其创建方式有两种: 方法一:Vector. ...
- jetbrains系列激活
没钱,只能DB了. 为了避免某些个人私自搭建服务器,以及自己搭建激活服务器,因此,决定使用破解包~~~. 注意:只要破解,就要屏蔽官方激活服务器:0.0.0.0 account.jetbrains.c ...
- 关闭Tomcat进程 一条语句(必看)
写在开始 MAC系统下进行JAVA研发,经常遇到的一个问题就是杀死异常Tomcat 通常都是用两条指令,先查询出Tomcat占用的进程,再kill掉该进程, 其实有一种联合语句的方式可以一条语句直接关 ...
- 七:Web Application Proxy
yarn自带了web接口,默认是和RM一起的(8088端口).但是为了减少从web接口受到的攻击,可以把Web接口单独放在别的机器上. 设置下web代理就行了 Configurations Confi ...
- appcan打包后产生的问题总结
以appcan为基础的项目,最终需要打包后进行调试.在调试过程中,主要的样式问题在苹果手机上,下面将这些问题总结起来,以防下次再犯. 1:ios 7 以上的手机中,状态栏与内容重叠: 问题描述:在io ...
- html+css基础 - 个人备忘录
//======================html部分===================// 表现内容<meta http-equiv="Content-Type" ...
- c# 编译的dll看不见注释问题
1.项目属性---->生成----->勾选XML文档文件: 2.使用的时候该文件和dll放在一块.