YbtOJ-相似子串【SA,RMQ,二分】

正题


题目大意

给出一个长度为nnn的字符串,两个串相似当且仅当可以通过每种字符置换使得它们相同。

qqq次询问这个字符串所有子串中和这个串中sl,rs_{l,r}sl,r子串有多少个相似的。

1≤n≤105,1≤q≤5×1051\leq n\leq 10^5,1\leq q\leq 5\times 10^51n105,1q5×105

字符集是数字0∼90\sim 909


解题思路

请问我是在阴间吗
请添加图片描述
首先对于相似的比较相信很常见,维护每个数字上一个和它相同的数字的距离,然后没有上一个就定为000就好了。

但是这题的问题在于我们提取出区间构成的数组时前面有些要变成000

同样的这也是个提示,因为字符集大小只有10,我们也可以从这里入手,对于一个后缀,我们把第一个出现的数字的位置挖空后,我们至多会把这个后缀以这些位置分成101010份,我们将这个字符串序列称之为这个后缀的值。

然后我们需要的就是这些后缀值的“LCP”,而这样我们需要我们能快速求这些后缀中字符串的LCP。

子串的LCP直接上SA+RMQ就好了。

这样我们把弄出来的后缀的值排好序,然后维护一个相邻的两两之间的"LCP"计入一个类似height的数组的东西。

然后对于询问我们就直接二分在RMQ上查询就好了。

时间复杂度:O(10nlog⁡n+qlog⁡n)O(10n\log n+q\log n)O(10nlogn+qlogn)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=1e5+10;
struct node{int l,r;
};
struct nstr{vector<node> r;int id;
}sr[N];
int n,m,q,nxt[10],p[10],pos[N];
int x[N],y[N],c[N],sa[N],rk[N];
int lg[N],f[N][20],h[N],s[N];
char rs[N];
void Qsort(){for(int i=1;i<=m;i++)c[i]=0;for(int i=1;i<=n;i++)c[x[i]]++;for(int i=1;i<=m;i++)c[i]+=c[i-1];for(int i=n;i>=1;i--)sa[c[x[y[i]]]--]=y[i],y[i]=0;return;
}
void Get_SA(){for(int i=1;i<=n;i++)x[i]=s[i]+1,m=max(m,s[i]+1),y[i]=i;Qsort();for(int w=1;w<=n;w<<=1){int p=0;for(int i=n-w+1;i<=n;i++)y[++p]=i;for(int i=1;i<=n;i++)if(sa[i]>w)y[++p]=sa[i]-w;Qsort();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]+w]==y[sa[i-1]+w])?p:(++p);if(p==n)break;m=p;}return;
}
void Get_Height(){int k=0;for(int i=1;i<=n;i++)rk[sa[i]]=i;for(int i=1;i<=n;i++){if(rk[i]==1)continue;if(k)k--;int j=sa[rk[i]-1];while(i+k<=n&&j+k<=n&&s[j+k]==s[i+k])k++;h[rk[i]]=f[rk[i]][0]=k;}return;
}
void Get_RMQ(){for(int i=2;i<=n;i++)lg[i]=lg[i>>1]+1;for(int j=1;(1<<j)<=n;j++)for(int i=1;i+(1<<j)-1<=n;i++)f[i][j]=min(f[i][j-1],f[i+(1<<j-1)][j-1]);return;
}
int RMQ(int l,int r){if(!l||!r)return 0;if(l==r)return n-l+1;l=rk[l];r=rk[r];if(l>r)swap(l,r);l++;int z=lg[r-l+1];return min(f[l][z],f[r-(1<<z)+1][z]);
}
int RMQs(int l,int r){l++;int z=lg[r-l+1];return min(f[l][z],f[r-(1<<z)+1][z]);
}
void SA(){Get_SA();Get_Height();Get_RMQ();return;
}
int cp(node x,node y){//x<=yif(!x.l&&!y.l)return 2;if(!x.l)return 1;if(!y.l)return 0;int len=RMQ(x.l,y.l);if(len>x.r-x.l||len>y.r-y.l){if(x.r-x.l==y.r-y.l)return 2;return (x.r-x.l)<(y.r-y.l);}return s[x.l+len]<s[y.l+len];
}
bool cmp(nstr x,nstr y){int i=0;while(1){if(i>=x.r.size())return 0;if(i>=y.r.size())return 1;int op=cp(x.r[i],y.r[i]);if(op==2)i++;else return op;}return 0;
}
int LCP(nstr x,nstr y){int i=0,ans=0;while(i<x.r.size()&&i<y.r.size()&&cp(x.r[i],y.r[i])==2)ans+=x.r[i].r-x.r[i].l+1,i++;if(i<x.r.size()&&i<y.r.size())ans+=min(RMQ(x.r[i].l,y.r[i].l),min(x.r[i].r-x.r[i].l,y.r[i].r-y.r[i].l)+1);return ans;
}
int main()
{
//	freopen("similar.in","r",stdin);
//	freopen("similar.out","w",stdout); scanf("%d%d",&n,&q);scanf("%s",rs+1);for(int i=1;i<=n;i++){if(!nxt[rs[i]-'0'])s[i]=0;else s[i]=i-nxt[rs[i]-'0'];nxt[rs[i]-'0']=i;}SA();memset(nxt,0,sizeof(nxt));for(int i=n;i>=1;i--){nxt[rs[i]-'0']=i;for(int j=0;j<=9;j++)p[j]=nxt[j];sort(p,p+10);int now=i;for(int j=0;j<=9;j++){if(!p[j])continue;if(p[j]>now)sr[i].r.push_back((node){now,p[j]-1});sr[i].r.push_back((node){0,0});now=p[j]+1;}if(now<=n)sr[i].r.push_back((node){now,n});sr[i].id=i;}sort(sr+1,sr+1+n,cmp);for(int i=1;i<=n;i++)pos[sr[i].id]=i;for(int i=2;i<=n;i++)h[i]=LCP(sr[i-1],sr[i]);for(int i=2;i<=n;i++)f[i][0]=h[i];for(int j=1;(1<<j)<=n;j++)for(int i=1;i+(1<<j)-1<=n;i++)f[i][j]=min(f[i][j-1],f[i+(1<<j-1)][j-1]);int las=0;while(q--){int l,r;scanf("%d%d",&l,&r);l^=las;r^=las;if(l>n||r>n||l<1||r<1)continue;int x=pos[l],len=r-l+1;int L=x+1,R=n,ans=1;while(L<=R){int mid=(L+R)>>1;if(RMQs(x,mid)>=len)L=mid+1;else R=mid-1;}ans+=R-x;L=1;R=x-1;while(L<=R){int mid=(L+R)>>1;if(RMQs(mid,x)>=len)R=mid-1;else L=mid+1;}ans+=x-L;printf("%d\n",las=ans);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317646.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员修仙之路--把用户访问记录优化到极致

点击上方蓝色字体&#xff0c;关注我们菜菜呀&#xff0c;前几天做的用户空间&#xff0c;用户反映有时候比较慢呀CEO,CTO,CFO于一身的CXO是吗&#xff1f;菜菜我把你拉进用户反馈群&#xff0c;你解决一下呀CEO,CTO,CFO于一身的CXO&#xff08;完了&#xff0c;以后没清净时候…

[国家集训队]航班安排 (最大费用最大流)

description 神犇航空有K架飞机&#xff0c;为了简化问题&#xff0c;我们认为每架飞机都是相同的。神犇航空的世界中有N个机场&#xff0c;以0…N-1编号&#xff0c;其中0号为基地机场&#xff0c;每天0时刻起飞机才可以从该机场起飞&#xff0c;并不晚于T时刻回到该机场。一…

新数据革命:开源图形化数据引擎Hawk5发布

Hawk是一款开源图形化的爬虫和数据清洗工具&#xff0c;GitHub Star超过2k&#xff0c;前几代版本介绍如下&#xff1a;Hawk3: 终于等到你: 图形化开源爬虫Hawk 3发布!Hawk2: 120项优化: 超级爬虫Hawk 2.0重磅发布&#xff01;Hawk1: 如何从互联网采集海量数据&#xff1f;租房…

[TJOI2018]智力竞赛 (匈牙利)

description 题目描述 小豆报名参加智力竞赛&#xff0c;他带上了 n个好朋友作为亲友团一块来参加比赛。 比赛规则如下&#xff1a;一共有 m道题目&#xff0c;每个人都有 1 次答题机会&#xff0c;每次答题为选择一道题目回答&#xff0c;在回答正确后&#xff0c;可以从这个…

ASP.NET Core如何在ActionFilterAttribute里做依赖注入

点击蓝字关注我在ASP.NET Core里&#xff0c;我们可以使用构造函数注入很方便地对Controller&#xff0c;ViewComponent等部件做依赖注入。但是如何给过滤器ActionFilterAttribute也用上构造函数注入呢&#xff1f;问题我的博客系统里有个用来删除订阅文件缓存的ActionFilter&a…

[八省联考2018]劈配 (匈牙利)

description 一年一度的综艺节目《中国新代码》又开始了。Zayid 从小就梦想成为一名程序员&#xff0c;他觉得这是一个展示自己的舞台&#xff0c;于是他毫不犹豫地报名了。 轻车熟路的 Zayid 顺利地通过了海选&#xff0c;接下来的环节是导师盲选&#xff0c;这一阶段的规则…

助力苏州、星火相传,广苏两地微软技术俱乐部交流纪实

2019年1月19日时值二十四节气“大寒”前夕&#xff0c;江南水乡冬日的寒气盖不住苏州.NET开发者的热情&#xff0c;就在这一天苏州微软技术俱乐部成立了并举办了第一场大型的线下交流活动。星火相传2018年12月8日广州.NET微软技术俱乐部举办了恢复以来的第一场大型线下技术交流…

微软技术专家为您解读深度学习

随着阿尔法狗、无人驾驶、智能翻译的横空出世&#xff0c;“人工智能”这个已经存在60多年的词语&#xff0c;仿佛一夜之间重新成为热词。同时被科技圈和企业界广泛提及的还有“机器学习”“深度学习”“神经网络”…… 但如此喧嚣热烈的气氛之下&#xff0c;大部分人对这一领域…

「LibreOJ NOI Round #2」不等关系 (dp+NTT分治)

description 戳我看题目哦 solution 有一道非常相似的题目 一棵树&#xff0c;每条边限制两个端点的大小关系&#xff08;限制 a[u]>a[v]a[u]>a[v]a[u]>a[v] 或 a[u]<a[v]a[u]<a[v]a[u]<a[v]&#xff09; 求有多少种符合要求的排列aaa满足整棵树的限制。n…

PCB 机器学习(ML.NET)初体验实现PCB加投率预测

使用ML.NET建立PCB加投率模型对单一蚀刻工序进行加投率预测, 此实例为最简单预测&#xff0c;要想实现全流程加投率预测挑战难度还是挺大的&#xff0c;可以查看另一种关于大数据在PCB行业应用---加投率计算基本原理:PCB 加投率计算实现基本原理--K最近邻算法&#xff08;KNN&a…

潘淳的苏州.NET俱乐部成立有感!附我的录音

引言&#xff1a;今天是1月21日&#xff0c;我&#xff08;潘淳&#xff09;的生日&#xff0c;两天前刚刚过了他&#xff08;苏俱&#xff09;的生日&#xff0c;微软技术俱乐部&#xff08;苏州&#xff09;在苏州微软正式成立。作为大会活动的策划者和活动发起者之一&#x…

十年 IT 老兵带你通过案例学架构,附C#代码

技术大会上的分享大多高大上&#xff0c;亿级流量、超大型研发团队&#xff0c;虽然值得借鉴&#xff0c;但由于应用场景与研发资源的差异&#xff0c;一般企业并不容易落地。其实&#xff0c;中小型研发团队在IT行业还是占大多数&#xff0c;他们在技术架构方面的问题较多&…

浅谈一致性Hash原理及应用

在讲一致性Hash之前我们先来讨论一个问题。问题&#xff1a;现在有亿级用户&#xff0c;每日产生千万级订单&#xff0c;如何将订单进行分片分表&#xff1f;小A&#xff1a;我们可以按照手机号的尾数进行分片&#xff0c;同一个尾数的手机号写入同一片/同一表中。大佬&#xf…

如何定义开发完成?(Definition of Done)

最近在拜读郑晔的10x程序员工作法&#xff0c;收益良多&#xff0c;文中提出一个概念叫DoD&#xff08;Definition of Done&#xff09;给我的感触颇深。这让我联想到实际工作过程中&#xff0c;经常遇到的扯皮、争吵等各种场景&#xff0c;其实就和这个DoD分不开。一、场景描述…

【正睿2021寒假省选第二轮集训 day 1】串 (后缀自动机+记忆化)

description 定义一个字符串的子串是这个字符串的某个连续区间的字符组成的串。比如&#xff0c;“djq"的子串是"d”,“j”,“q”,“dj”,“jq”,和"djq"。 定义F(a,b)为最长在字符串bb中至少出现一次的字符串a的子串&#xff0c;例如&#xff1a; F(“d…

欧拉筛法的应用

[数论]-----欧拉筛法的应用 文章目录1.求1~n之间的所有质数2.求1~n之间所有自然数的欧拉函数φ&#xff08;x&#xff09;3.求1~n之间的每个数的因子个数详细推导&#xff1a;代码&#xff1a;4.求1~n之间每个数的因数和详细的推导&#xff1a;代码&#xff1a;筛法求莫比乌斯函…

全新尝试|ComponentOne WinForm和.NET Core 3.0

在微软 Build 2018 开发者大会上&#xff0c;.NET 团队公布了 .NET Core 的下一个主要版本 .NET Core 3.0 的规划蓝图&#xff1a;.NET Core 3将开始支持 Windows 桌面应用程序&#xff0c;包括 Windows Form、Windows Presentation Framework&#xff08;WPF&#xff09;和UWP…

[bzoj3625][Codeforces Round #250]小朋友和二叉树 (生成函数)

description 我们的小朋友很喜欢计算机科学&#xff0c;而且尤其喜欢二叉树。 考虑一个含有n个互异正整数的序列c[1],c[2],…,c[n]。如果一棵带点权的有根二叉树满足其所有顶点的权值都在集合{c[1],c[2],…,c[n]}中&#xff0c;我们的小朋友就会将其称作神犇的。并且他认为&am…

H - Tunnel Warfare HDU - 1540

H - Tunnel Warfare HDU - 1540 题意&#xff1a; n个数顺序排列&#xff0c;左右数相连&#xff0c; 现在有三个操作&#xff1a; 1.摧毁一个位置上的数 2.回复上一次摧毁的数 3.查询包含该位置的最长连续区间长度 题解&#xff1a; 有两个方法&#xff0c;第一个是区间的…

2019年1月已到,Java 8 要收费了吗?

根据此前开源中国发起的 Java 版本使用调查&#xff0c;国内的 Java 主力版本仍是 Java 8&#xff0c;有近 70% 的用户表示仍在使用 Java 8。所以对于「Java 8 是否要收费」这个问题&#xff0c;十分有必要阐述清楚&#xff0c;以消除不必要的恐慌。首先要明确一点&#xff0c;…