[BZOJ3230]相似子串(后缀数组+二分+ST表)

BZOJ3230相似子串测试数据 BZOJ3230相似子串的测试数据,希望能够帮到大家。 立即下载

=== ===

这里放传送门

=== ===

题解

这道题实际上就是给定子串的排名然后求它们的LCP和LCS。所以首先需要对正串和反串分别建立后缀数组,求出height。因为要计算LCP和LCS就要知道它们在正串和反串中所处的位置,所以就考虑如何根据给定的排名求这个东西。在后缀数组里求不相同子串的时候就是按照后缀的排名,每次用这个后缀的前缀数量减去和前一个后缀重复的前缀数量也就是它的height然后再累加到答案里。那也就是说按照字典序考察每个后缀的时候,它贡献的子串也是按照字典序排列的。那么可以考虑二分,把每个后缀贡献的子串求出来存在数组里再做一个前缀和然后在这个数组里二分。这样就可以得到排名为k的子串是由哪一个后缀贡献的,接着就可以得到它在这个后缀里的位置然后就可以得到它原本的长度。在用height数组求LCP和LCS的时候对子串长度取一下Min就没问题了。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define Pow 18
#define clear(x)(memset(x,0,sizeof(x)));
using namespace std;
const long long inf=1e18;
int len,q,Xx[100010],Yy[100010],b[100010],m,p,*x,*y,lg[100010];
long long v[100010];
char s[100010];
bool cmp(int i,int j,int l){
    return y[i]==y[j]&&((i+l>=len)?-1:y[i+l])==((j+l>=len)?-1:y[j+l]);
}
struct SuffixArray{
    int SA[100010],rank[100010],height[100010],Min[100010][20];
    void get(){
        clear(b);x=Xx;y=Yy;m=200;
        for (int i=0;i<len;i++) ++b[x[i]=s[i]];
        for (int i=1;i<=m;i++) b[i]+=b[i-1];
        for (int i=len-1;i>=0;i--) SA[--b[x[i]]]=i;
        for (int k=1;k<=len;k<<=1){
            p=0;
            for (int i=len-k;i<len;i++) y[p++]=i;
            for (int i=0;i<len;i++)
              if (SA[i]>=k) y[p++]=SA[i]-k;
            for (int i=0;i<=m;i++) b[i]=0;
            for (int i=0;i<len;i++) ++b[x[i]];
            for (int i=1;i<=m;i++) b[i]+=b[i-1];
            for (int i=len-1;i>=0;i--) SA[--b[x[y[i]]]]=y[i];
            swap(x,y);x[SA[0]]=0;p=1;
            for (int i=1;i<len;i++)
              x[SA[i]]=cmp(SA[i-1],SA[i],k)?p-1:p++;
            if (p>=len) break;m=p;
        }
        p=0;
        for (int i=0;i<len;i++) rank[SA[i]]=i;
        for (int i=0;i<len;i++){
            if (rank[i]==0) continue;
            int j=SA[rank[i]-1];
            while (i+p<len&&j+p<len&&s[i+p]==s[j+p]) ++p;
            height[rank[i]]=p;
            if (p!=0) --p;
        }
        for (int i=0;i<len;i++) Min[i][0]=height[i];
        for (int i=1;i<=Pow;i++)
          for (int j=0;j<len;j++){
              int pos=j+(1<<(i-1));
              if (pos>=len) continue;
              Min[j][i]=min(Min[j][i-1],Min[pos][i-1]);
          }
    }
    int ask(int l,int r,int limit){
        int ans,j;
        l=rank[l];r=rank[r];
        if (l==r) return limit;
        if (l>r) swap(l,r);
        l++;j=lg[r-l+1];
        ans=min(Min[l][j],Min[r-(1<<j)+1][j]);
        ans=min(ans,limit);
        return ans;
    }
}P,N;
void getstr(int len){
    char c;
    for (int i=0;i<len;i++){
        c=getchar();
        while (c<'a'||c>'z') c=getchar();
        s[i]=c;
    }
}
void reverse(){
    for (int i=0;i+i<len;i++)
      swap(s[i],s[len-i-1]);
}
int find(int l,int r,long long x,int &L){
    int mid;
    long long res=x;
    while (l!=r){
        mid=(l+r)>>1;
        if (v[mid]>=x) r=mid;
        else l=mid+1;
    }
    if (l==len) return -1;
    if (l!=0) res-=v[l-1];
    L=res+P.height[l];//计算当前子串的长度
    return P.SA[l];
}
int main()
{
    scanf("%d%d",&len,&q);
    for (int i=1,p=0;i<=len;i++){
        while ((1<<p)<=i) ++p;
        lg[i]=p-1;
    }
    getstr(len);P.get();
    reverse();N.get();
    for (int i=0;i<len;i++) v[i]=len-P.SA[i]-P.height[i];
    for (int i=1;i<len;i++) v[i]+=v[i-1];
    v[len]=inf;//便于判断无解
    for (int i=1;i<=q;i++){
        int xp,yp,xl,yl,limit;
        long long x,y,LCP,LCS;
        scanf("%I64d%I64d",&x,&y);
        xp=find(0,len,x,xl);
        yp=find(0,len,y,yl);
        if (xp==-1||yp==-1){
            printf("-1\n");continue;
        }
        limit=min(xl,yl);//注意LCP和LCS的最长长度不能超过子串长度
        LCP=P.ask(xp,yp,limit);
        xp=xp+xl-1;yp=yp+yl-1;
        xp=len-xp-1;yp=len-yp-1;//求出当前这个串在反串中的位置
        LCS=N.ask(xp,yp,limit);
        LCP*=LCP;LCS*=LCS;
        printf("%I64d\n",LCP+LCS);
    }
    return 0;
}
STM32F407步进电机控制及DM542驱动器使用 基于DM542驱动器的步进电机简单控制 阅读详情

相关推荐

SAP SD模块进阶:VA31和VA01底层竟是同一个BAPI?揭秘销售单据创建的统一逻辑

本文深入解析SAP SD模块中VA31和VA01的底层统一架构设计,揭示两者如何通过同一个BAPI `SD_SALESDOCUMENT_CREATE`实现销售单据创建。通过ABAP调试和参数化设计分析,展示了SAP如何利用单据类型(doc_type)等关键字段实现业务逻辑复用,为开发者提供配置化设计的重要启示。

weixin_30561177的博客 244

bzoj3230: 相似子串(后缀数组+ST表)

题解:后缀数组+稀疏表 对原串正反向建后缀数组并通过height数组求出本质不同字符串个数。 通过ST表预处理后可在O(1)时间内求出LCQ。代码:#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<cmath>

DZYO的博客 446

告别130MB/s瓶颈!用Zynq+NVMe实现1.2GB/s高速存储的PL数据分流实战

本文详细介绍了如何通过Zynq+NVMe实现1.2GB/s高速存储的PL数据分流方案,突破传统Zynq架构130MB/s的瓶颈。文章分享了PL直连NVMe的硬件架构设计、软件栈优化及性能调优实战技巧,帮助开发者实现高速数据流的稳定存储。

weixin_42653691的博客 372

BZOJ 3230 相似子串|后缀数组|RMQ

良心提示。 f=两子串的最长公共前缀后缀长度平方和的最大值。 因此开2个后缀数组分别处理前后缀。 而且得开long long..对于每个子串,其排名与后缀的排名有关,因此对于查询的子串我们找到产生该子串的后缀,而我们可以通过计算前i个后缀产生了多少个子串,并查询之得(STL大法好)。于是RMQ解决之。代码稍后贴…3230: 相似子串Time Limit: 20 Sec Memory Limi

とある黄鱼のOIブログ 968

【深度学习驱动流体力学】采集OpenFOAM仿真数据作为AI模型训练数据集与卷积神经网络搭建到预测(一站式完整代码实现)

采集OpenFOAM仿真数据作为AI模型训练数据集与卷积神经网络搭建到预测(一站式完整代码实现)

源代码杀手的博客 1414

【Power Compiler手册】4.saif文件

功耗计算的准确性取决于切换活动数据的准确性。这些数据是通过使用RTL仿真或门级仿真生成的,并存储在SAIF文件中。在执行功耗优化和分析之前,应该使用SAIF文件来反标设计对象上的切换活动信息。SAIF是由Synopsys支持的ASCII格式,用于促进不同Synopsys工具之间的信息交换(参见IEEE 1801标准,附录J)。使用`read_saif`命令读取SAIF文件,使用`write_saif`命令写出SAIF文件。有关更多信息,请参见`read_saif`和`write_saif`命令的手册页。

QRBQ 2187

别再死记硬背达西定律了!用Python模拟地下水流动,直观理解渗流速度与达西速度的区别

本文通过Python编程模拟地下水流动,直观展示达西定律中渗流速度与达西速度的区别。文章详细介绍了砂管模型的构建、溶质运移模拟及参数影响分析,帮助读者从动态可视化中深入理解地下水动力学核心概念,摆脱传统死记硬背的学习方式。

weixin_30471561的博客 417

在lio_sam中融入GPS

在LIO(激光惯性里程计)系统中,将GPS信息融合到里程计中,借助GTSAM(Georgia Tech Smoothing and Mapping)库进行因子图优化,可以有效提升全局定位精度。当进入到GPS信号不好或缺失的环境中,需要借助融合后的里程计反算经纬度,来获取高精度的定位信息。利用GeographicLib第三方库将经纬度投影到局部笛卡尔坐标系中。

如果想成为中心,那么就到中心去吧。 1211

BZOJ3230: 相似子串【后缀数组】

Description Input 输入第1行,包含3个整数N,Q。Q代表询问组数。 第2行是字符串S。 接下来Q行,每行两个整数i和j。(1≤i≤j)。 Output 输出共Q行,每行一个数表示每组询问的答案。如果不存在第i个子串或第j个子串,则输出-1。 Sample Input 5 3 ababa 3 5 5 9 8 10 Sample Output 18 16 -1 HINT 样例解释 ...

weixin_30673715的博客 142

YOLOv13涨点改进| CVPR 2026 |独家创新首发、主干改进篇 |利用RIS-PiDiNet主干让YOLOv13更加强大!适合遥感目标检测、小目标检测、旋转目标检测,变化检测,图像分割涨点

🔥本文提出了一种改进的RIS-PiDiNet主干网络,通过引入几何先验构建几何一致性检测器,显著提升了模型在任意方向、结构规则目标场景下的检测性能。包含两个核心模块:S-PDC利用极谐变换的谐波核建模目标结构对称性,RIS-PDC通过SO(2)群平均实现旋转不变性。网络采用基于RIS-block的主干结构并融合轻量级LBP特征,增强了细粒度结构表达能力。实验表明,该方法特别适用于遥感和复杂几何分布场景,能有效提升目标检测的鲁棒性和精度。文章还详细介绍了如何将RIS-PiDiNet集成到YOLOv13框架

Ai缝合怪、助力小伙伴高效发论文 90

8、内存交织技术详解

本文详细解析了内存交织技术的基本原理、工作机制及实现方式,探讨了其在提升内存访问速度和系统性能中的关键作用。文章还分析了内存交织的优缺点、实际应用场景以及与其他优化技术的结合应用,并提出了未来发展的可能方向,为理解与运用该技术提供了全面参考。

g9h0i1的博客 549

BZOJ3230 相似子串[后缀数组+二分+st表]

BZOJ3230 相似子串 给一个串,查询排名i和j的子串longest common suffix和longest common prefix 思路其实还是蛮好想的,就是码起来有点恶心。可以发现后缀拍完序之后的子串可以根据sa自前而后的顺序标子串排名,和统计不同字串那里差不多,自lcp后的是新子串,开始标记排名。实际操作时在每个后缀上标这一后缀开始第一个新子串排名,可证是单调增的,...

dianer2977的博客 214

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

BZOJ 3230 相似子串 | 后缀数组 二分 ST表

BZOJ 3230 相似子串 题面 题解 首先我们要知道询问的两个子串的位置。 先正常跑一遍后缀数组并求出height数组。 对于每一个后缀suffix(i),考虑以i开头的子串有多少是之前没有出现过的,也就是考虑左端点在i、右端点在什么范围内时这个子串没有出现过——答案是右端点在[i + height[i] - 1, n]范围内时这个子串没出现过,即右端点在没有被“i与排在前一个的后缀的公共前...

weixin_30394633的博客 176

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

[BZOJ3230]相似子串(后缀数组+二分+st表)

题目描述传送门题解题目实际上是要求最长公共前缀和后缀的长度的平方和。个人认为题目描述中a和b应该取min 把这个串正反都求一下sa和height 由于是本质不同的子串,所以每一个后缀的贡献应该是当前串刨去它和前一个的lcp的剩下的前缀 可以求出贡献的前缀和,显然满足单调性 对于每组询问,二分找出这两个子串在rank里的位置,然后用rmq求区间最小值 再找出这两个子串的结尾的位置,在反串那边

zyf2000 1087

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

BZOJ 3230 相似子串 后缀数组+二分+ST表

Description Input 输入第1行,包含3个整数N,Q。Q代表询问组数。 第2行是字符串S。 接下来Q行,每行两个整数i和j。(1≤i≤j)。 Output 输出共Q行,每行一个数表示每组询问的答案。如果不存在第i个子串或第j个子串,则输出-1。 Sample Input 5 3 ababa 3 5 5 9 8 10

I'm Growing 401

[BZOJ3230]相似子串

[BZOJ3230]相似子串 试题描述 输入 输入第1行,包含3个整数N,Q。Q代表询问组数。第2行是字符串S。接下来Q行,每行两个整数i和j。(1≤i≤j)。 输出 输出共Q行,每行一个数表示每组询问的答案。如果不存在第i个子串或第j个子串,则输出-1。 输入示例 5 3 ababa 3 5 5 9 8 10 输出示例 18 16 ...

weixin_30344795的博客 121

相似子串 BZOJ 3230 后缀数组模板题

相似子串 BZOJ 3230 后缀数组模板题 时间2019 8 10——这题网上似乎找不到了,但是我有数据哟 这道题其实非常简单,但是我场上并没有想出来。。。。 现在拿出来补补智商 首先我们求出后缀数组sa[] height[] Rank[] 数组,到这我们的基本条件就已经具备了 然后再根据我们对后缀数组的理解:两个排名不相邻的最长公共前缀定义为排名在它们之间的Height的最小值 RMQ问题当然...

qq_33437973的博客 219

BZOJ 3230: 相似子串

Description 求本质不同的子串排名为\(i,j\)的两个子串最长公共前缀和最长公共后缀的平方。\(n\leqslant 10^5,q\leqslant 10^5\) Solution 后缀数组+ST表。 本质不同的子串可以用过\(n-sa[i]+1-ht[i]\)得到一个后缀的本质不同后缀的贡献。 然后统计出来前缀和,在上面二分就可以得到位置和长度。 最长公共前缀就...

aisen1985的博客 197

Bzoj3230 相似子串

Time Limit:20 SecMemory Limit:128 MBSubmit:1783Solved:444[Submit][Status][Discuss] Description Input 输入第1行,包含3个整数N,Q。Q代表询问组数。第2行是字符串S。接下来Q行,每行两个整数i和j。(1≤i≤j)。 Outp...

dezhen7015的博客 169

BZOJ3230 相似子串 字符串 SA ST表

原文链接http://www.cnblogs.com/zhouzhendong/p/9033092.html 题目传送门 - BZOJ3230 题意   给定字符串$s$。长度为$n$。   现在有$Q$组询问,每组询问内容如下:   两个正整数$i,j$。   设$s_i,s_j$分别表示$s$的所有本质不同的子串中字典序第$i$小和第$j$小的子串。   请你输出$|lcp(s_...

weixin_30900589的博客 188

BZOJ3230 相似子串

这个题思路应该算是比较简单的…… 先扫一遍height,算出前i个后缀中含有的不同子串个数,然后在这个和中二分,找到一个排名对应的子串。 然后就是最长公共前缀和最长公共后缀……用两个后缀数组即可完成所有操作。 但是我有两个之前写错了的地方: 1、没有开long long 2、注意算LCP的时候,要算RMQ(rank[p]+1,rank[q]),但如果rank[p],rank[q]大小关系

KuribohG 1480

[BZOJ3230] 相似字串 后缀数组+RMQ

3230: 相似子串 Time Limit:20 SecMemory Limit:128 MB Description Input 输入第1行,包含3个整数N,Q。Q代表询问组数。第2行是字符串S。接下来Q行,每行两个整数i和j。(1≤i≤j)。 Output 输出共Q行,每行一个数表示每组询问的答案。如果不存在第i个子串或第j个子串,则输出-1。 Sample ...

weixin_30556161的博客 120

bzoj3230

以前觉得这题好难,现在觉得这题还是挺简单首先看到类似LCP问题不难想到后缀数组吧前后的相似需要我们分别做一个后缀数组和“前缀数组”(就是把字符串反向然后跑后缀数组)这道题的难点就在于如何确定子串是什么考虑到一个有用的结论:任何一个子串都是某一个后缀的某一个前缀由于做完后缀数组之后,后缀已经按照从小到大排列了因此考虑相邻名次后缀sa[i]和sa[i-1],然后在这两个后缀间,还夹着一些子串不难发现,...

weixin_34378922的博客 133

字符串题表

已完成AC自动机:bzoj1559 ** AC自动机+矩乘bzoj1195:[HNOI2006]最短母串 ** AC自动机+矩乘后缀数组:bzoj1692 * SAbzoj1031 * SAbzoj3796 ** SA+KMPbzoj3230:相似子串 ** SA+ST表bzoj4698 *** SAmanacher:bzoj2160:拉拉队排练 * manacherbzoj3790 * mana...

weixin_30672295的博客 123
上一篇: [BZOJ2850]巧克力王国(K-D tree)
下一篇: [BZOJ2406]矩阵(二分+有上下界的网络流)
FromATP
博客等级 码龄10年 75粉丝 163原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值