题目链接

BZOJ3230
权限题

题解

后缀数组基础题
询问第K大不同子串和正反lcp长度
如果您RE了,您就要知道询问的输入会爆LL

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 400005,maxm = 100005,INF = 1000000000;
inline LL read(){LL out = 0,flag = 1; char c = getchar();while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}return out * flag;
}
int n,m,bac[maxn],t1[maxn],t2[maxn],bin[50],Log[maxn];
LL sum[maxn];
struct SA{char s[maxn];int sa[maxn],rank[maxn],height[maxn],mn[maxn][18];void getsa(){int *x = t1,*y = t2; m = 255;for (int i = 0; i <= m; i++) bac[i] = 0;for (int i = 1; i <= n; i++) bac[x[i] = s[i]]++;for (int i = 1; i <= m; i++) bac[i] += bac[i - 1];for (int i = n; i; i--) sa[bac[x[i]]--] = i;for (int k = 1; k <= n; k <<= 1){int p = 0;for (int i = n - k + 1; i <= n; i++) y[++p] = i;for (int i = 1; i <= n; i++) if (sa[i] - k > 0) y[++p] = sa[i] - k;for (int i = 0; i <= m; i++) bac[i] = 0;for (int i = 1; i <= n; i++) bac[x[y[i]]]++;for (int i = 1; i <= m; i++) bac[i] += bac[i - 1];for (int i = n; i; i--) sa[bac[x[y[i]]]--] = y[i];swap(x,y);x[sa[1]] = p = 1;for (int i = 2; i <= n; i++)x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k] ? p : ++p);if (p >= n) break;m = p;}for (int i = 1; i <= n; i++) rank[sa[i]] = i;for (int i = 1,k = 0; i <= n; i++){if (k) k--;int j = sa[rank[i] - 1];while (s[i + k] == s[j + k]) k++;height[rank[i]] = k;}for (int i = 1; i <= n; i++) mn[i][0] = height[i];for (int j = 1; j <= 17; j++)for (int i = 1; i <= n; i++){if (i + bin[j] - 1 > n) break;mn[i][j] = min(mn[i][j - 1],mn[i + bin[j - 1]][j - 1]);}}int lcp(int x,int y){if (x == y) return n - x + 1;int l = rank[x],r = rank[y];if (l > r) swap(l,r); l++;int t = Log[r - l + 1];return min(mn[l][t],mn[r - bin[t] + 1][t]);}
}L,R;
void init(){sum[1] = n - L.sa[1] + 1;for (int i = 2; i <= n; i++)sum[i] = sum[i - 1] + (n - L.sa[i] + 1) - L.height[i];
}
int q;
void solve(){LL f,a,b,x,y;int l1,r1,l2,r2;while (q--){x = read(); y = read();if (x > sum[n] || y > sum[n]) {puts("-1"); continue;}int p = lower_bound(sum + 1,sum + 1 + n,x) - sum;int q = lower_bound(sum + 1,sum + 1 + n,y) - sum;if (sum[p] == x) l1 = L.sa[p],r1 = n;else l1 = L.sa[p],r1 = n - (sum[p] - x);if (sum[q] == y) l2 = L.sa[q],r2 = n;else l2 = L.sa[q],r2 = n - (sum[q] - y);a = min(L.lcp(l1,l2),min(r1 - l1 + 1,r2 - l2 + 1));b = min(R.lcp(n - r1 + 1,n - r2 + 1),min(r1 - l1 + 1,r2 - l2 + 1));f = a * a + b * b;printf("%lld\n",f);}
}
int main(){bin[0] = 1; for (int i = 1; i <= 30; i++) bin[i] = bin[i - 1] << 1;Log[0] = -1; for (int i = 1; i <= 100000; i++) Log[i] = Log[i >> 1] + 1;n = read(); q = read();scanf("%s",L.s + 1);for (int i = 1; i <= n; i++) R.s[i] = L.s[n - i + 1];L.getsa(); R.getsa();init(); solve();return 0;
}

转载于:https://www.cnblogs.com/Mychael/p/9036417.html

BZOJ3230 相似子串 【后缀数组】相关推荐

  1. 寻找一个字符串的重复子串 后缀数组

    什么是后缀数组 令字符串 S=S[1]S[2]...S[n]S=S[1]S[2]...S[n]{\displaystyle S=S[1]S[2]...S[n]} , S[i,j]S[i,j]{\dis ...

  2. poj 3261 后缀数组 找反复出现k次的子串(子串能够重叠)

    题目:http://poj.org/problem?id=3261 仍然是后缀数组的典型应用----后缀数组+lcp+二分 做的蛮顺的,1A 可是大部分时间是在调试代码.由于模板的全局变量用混了,而自 ...

  3. SPOJ - PHRASES Relevant Phrases of Annihilation —— 后缀数组 出现于所有字符串中两次且不重叠的最长公共子串...

    题目链接:https://vjudge.net/problem/SPOJ-PHRASES PHRASES - Relevant Phrases of Annihilation no tags  You ...

  4. poj1743(后缀数组:最长不可重叠子串长度)

    链接:http://poj.org/problem?id=1743 题意: 给你n个数字,挨个作差,求这n-1个数字的最长不可重叠子串长度. 思路: 罗大牛就是6.看了罗牛的后缀数组PDF.这道题是后 ...

  5. 后缀数组求最长重复子串

    问题描述 给定一个字符串,求出其最长重复子串 例如:abcdabcd 最长重复子串是 abcd,最长重复子串可以重叠 例如:abcdabcda,这时最长重复子串是 abcda,中间的 a 是被重叠的. ...

  6. poj 3261 Milk Patterns 后缀数组 最长重复子串

    http://poj.org/problem?id=3261 给一串数组,数组最少含有k个相同子串,可重叠,求这样子串的最长长度. 后缀数组求出 height[],若连续k个height[]都大于mi ...

  7. POJ 1743 (后缀数组+不重叠最长重复子串)

    题目链接: http://poj.org/problem?id=1743 题目大意:楼教主の男人八题orz.一篇钢琴谱,每个旋律的值都在1~88以内.琴谱的某段会变调,也就是说某段的数可以加减一个旋律 ...

  8. [SDOI2016] 生成魔咒(后缀数组SA + st表 + set)动态不同子串个数

    problem luogu-P4070 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1,21,21,2 拼凑起来形成一个魔咒串 [1,2][1,2][1,2]. 一个魔咒串 ...

  9. 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数

    目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...

最新文章

  1. SpringMVC处理Date类型的成员变量方法
  2. CSS Sprites (转)
  3. Qt lnk1158 无法运行rc.exe 解决
  4. objective-c ——代码块
  5. OpenGL textures纹理的实例
  6. java统计行列和字数的函数_JAVA使用POI获取Excel的列数与行数
  7. 在windows下运行spark
  8. OpenCV_ cv2.imshow()
  9. Python爬虫从入门到放弃(二十)之 Scrapy分布式原理
  10. 【转】:TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute
  11. python变成exe1023无标题_GitHub - Qing1023/Python-100-Days: Python - 100天从新手到大师
  12. 系分架构 - 软件架构设计
  13. Network (哈工大网课笔记)
  14. 这款国产工具,让我电脑里的PS、XD都落灰了
  15. Linux——挂载硬盘
  16. 让IE浏览器支持HTML5标准的方法
  17. A44-网页前端第四次笔记
  18. LibreOffice SDK 开发环境配置(Windows)
  19. 精仿CNZZ网站访客统计系统源码 | 网页访客抓取采集源码 | 网站访客流量统计源码
  20. BeagleBoard XM 开发板入手

热门文章

  1. MsSql.RestApi - 构建ASP.NET REST API的最简单方法
  2. odoo10参考系列--ORM API 三(字段、继承与扩展、域和更新到新API)
  3. 机器人施教器的信息丢失_一种精准定位学习难度的施教方法及教育机器人与流程...
  4. python导入模块介绍_详解Python模块导入方法
  5. sql科学计数法转换为普通数字_Python3数据类型之数字-Python入门到精通
  6. 循环计数_FOR 循环
  7. 向量二次规划matlab,MATLAB中使用Opti Toolbox的混合整数二次规划
  8. java hibernate更新_Hibernate更新某些字段的几种update方法
  9. MySQL insert not exists插入唯一数据
  10. polkit启动失败_linux某服务启动失败,提示Authorization not available. Check if polkit...问题解决...