bzoj3277 串 (后缀数组+二分答案+ST表)

常见操作:先把所有串都连到一起,但中间加上一个特殊的符号(不能在原串中/出现过)作为分割

由于全部的子串就等于所有后缀的所有前缀,那我们对于每一个后缀,去求一个最长的前缀,来满足这个前缀在至少K个原串中出现过

那我们就二分一下这个前缀的长度。现在的问题就是怎么判断这个前缀是否在K个串中出现过了。

显然,对于一个后缀s的长度为x的前缀,只要某个后缀t 和s的LCP>=x,就说明x也是t的后缀

我们知道,LCP(x,y)=min{height[rank[y]],height[rank[y]-1],...,height[rank[x]+1]},所以其实t和s的LCP也是单调的,满足条件的是一个排名区间

那我们用二分出来这个区间的左右端点(用st表预处理一下height的区间最小值),然后只要判断这个区间里的后缀是否满足出现在K个串中就可以了

我们只要提前处理出来left[i],表示一个最大的排名,使得sa[left[i]]...sa[i]在不同串中出现次数>=K,然后判断我刚二分出来的那个区间[l,r],是否l<=left[r]就可以了

复杂度$O(nlog^2n)$,据说有点卡常,那稍微优化一下

我们第一次二分前缀的长度的时候,显然现在在做的的最大的长度一定是>=(上一个后缀的最大前缀长度-1)的,所以只要像求height那样推着做就可以了

据说均摊复杂度O(nlogn)

(第一次写后缀数组各种懵...最后还是全都照着大佬的题解抄的...)

  1 #include<bits/stdc++.h>
  2 #define pa pair<int,int>
  3 #define ll long long
  4 using namespace std;
  5 const int maxn=2e5+10;
  6 
  7 inline ll rd(){
  8     ll x=0;char c=getchar();int neg=1;
  9     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
 10     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
 11     return x*neg;
 12 }
 13 
 14 int NN,N,M,K;
 15 char ch[maxn];
 16 int suf[maxn],rank[maxn],rank1[maxn],cnt[maxn],tmp[maxn];
 17 int h[maxn],left0[maxn],bel[maxn],st[maxn][20],pos[maxn][2];
 18 
 19 inline void getsuf(){
 20     int i,j,k;M=126;
 21     for(i=1;i<=N;i++) cnt[ch[i]]=1;
 22     for(i=1;i<=M;i++) cnt[i]+=cnt[i-1];
 23     for(i=N;i;i--) rank[i]=cnt[ch[i]];
 24     for(k=1;j!=N;k<<=1){
 25         memset(cnt,0,sizeof(cnt));
 26         for(i=1;i<=N;i++) cnt[rank[i+k>N?0:i+k]]++;
 27         for(i=1;i<=M;i++) cnt[i]+=cnt[i-1];
 28         for(i=N;i;i--) tmp[cnt[rank[i+k>N?0:i+k]]--]=i;
 29         memset(cnt,0,sizeof(cnt));
 30         for(i=1;i<=N;i++) cnt[rank[i]]++;
 31         for(i=1;i<=M;i++) cnt[i]+=cnt[i-1];
 32         for(i=N;i;i--) suf[cnt[rank[tmp[i]]]--]=tmp[i];
 33         memcpy(rank1,rank,sizeof(rank));
 34         rank[suf[1]]=j=1;
 35         for(i=2;i<=N;i++){
 36             int ipk=suf[i]+k>N?0:suf[i]+k,i1pk=suf[i-1]+k>N?0:suf[i-1]+k;
 37             if(rank1[ipk]!=rank1[i1pk]||rank1[suf[i]]!=rank1[suf[i-1]]) j++;
 38             rank[suf[i]]=j;
 39         }M=j;
 40     }
 41     for(i=1;i<=N;i++) suf[rank[i]]=i;
 42 }
 43 
 44 inline void geth(){
 45     //h[1]=1;
 46     for(int i=1,j=0;i<=N;i++){
 47         if(rank[i]==1) continue; 
 48         if(j) j--;
 49         int x=suf[rank[i]-1];
 50         while(i+j<=N&&x+j<=N&&ch[i+j]==ch[x+j]) j++;
 51         h[rank[i]]=j;
 52     }
 53 }
 54 
 55 inline void getleft0(){
 56     int n=0;
 57     memset(cnt,0,sizeof(cnt));
 58     for(int i=1,j=1;i<=N;i++){
 59         if(ch[suf[i]]=='z'+1) continue;
 60         if(!cnt[bel[suf[i]]]) n++;
 61         cnt[bel[suf[i]]]++;
 62         if(n>=K){
 63             for(;n-(cnt[bel[suf[j]]]==1)>=K;n-=(cnt[bel[suf[j++]]]==0)) cnt[bel[suf[j]]]--;
 64             left0[i]=j;
 65         }
 66     }
 67 }
 68 
 69 inline void getst(){
 70     for(int i=N;i;i--){
 71         st[i][0]=h[i];
 72         for(int j=1;st[i+(1<<(j-1))][j-1];j++){
 73             st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
 74         }
 75     }
 76 } 
 77 
 78 inline int rmq(int l,int r){
 79     int k=log2(r-l+1);
 80     return min(st[l][k],st[r-(1<<k)+1][k]);
 81 }
 82 
 83 inline bool check(int p,int x){
 84     int l,r,l0,r0;
 85     if(h[p+1]<x) r0=p;
 86     else{
 87         l=p+1;r=N;
 88         while(l<=r){
 89             int m=(l+r)>>1;
 90             if(rmq(p+1,m)>=x)r0=m,l=m+1;
 91             else r=m-1;
 92         }
 93     }
 94     if(h[p]<x) l0=p;
 95     else{
 96         l=2;r=p;
 97         while(l<=r){
 98         //    printf("%d %d\n",l,r);
 99             int m=(l+r)>>1;
100             if(rmq(m,p)>=x) l0=m,r=m-1;
101             else l=m+1;
102         }l0--;
103     }
104     return left0[r0]>=l0;
105 }
106 
107 inline void solve(){
108     for(int i=1;i<=NN;i++){
109         int k=0;ll ans=0;
110         for(int j=pos[i][0];j<pos[i][1];j++){
111             if(k) k--;
112             for(;j+k<pos[i][1]&&check(rank[j],k+1);k++);
113             ans=ans+k;
114         }
115         printf("%lld ",ans);
116     }printf("\n");
117 }
118 
119 
120 
121 int main(){
122     //freopen("3277.in","r",stdin);
123 //    freopen("aa.out","w",stdout);
124     int i,j,k;
125     N=NN=rd(),K=rd();
126     for(i=1,j=1;i<=N;i++){
127         pos[i][0]=j;
128         scanf("%s",ch+j);k=strlen(ch+j);
129         ch[j+k]='z'+1;
130         for(int t=j;t<j+k;t++) bel[t]=i;
131         j=j+k+1;
132         pos[i][1]=j-1;
133     }N=j-1;
134     getsuf();
135     geth();
136     getleft0();
137     getst();
138     solve();
139     return 0;
140 }

 

转载于:https://www.cnblogs.com/Ressed/p/9677823.html

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

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

相关文章

微型计算机实验报告温度控制,单片机、可编程控制器实验教学大纲.doc

单片机、可编程控制器实验教学大纲.doc单片机、可编程控制器实验教学大纲 一、实验课的性质与任务 本实验课是在学生学完单片机原理与应用课程之后&#xff0c;为巩固提高所学知识&#xff0c;而安排的一次综合设计实验。通过本实验使学生将所学的单片机硬件结构、工作原理、编…

电脑word在哪_Word论文里的公式怎么编辑?这4个小工具帮你一分钟搞定!

临近毕业时&#xff0c;不少小可爱都在为论文头秃&#xff01;搜索并下载论文&#xff0c;论文排版&#xff0c;论文查重&#xff0c;这些我们之前已经写过相关文章啦&#xff01;Tools指南推荐搜索论文论文排版论文查重论文网站今天&#xff0c;再来给大家分享一个写论文时经常…

RTree算法及介绍

空间索引是对存储在介质上的数据位置信息的描述&#xff0c;用来提高系统对数据获取的效率。GIS涉及的各种海量复杂数据存储于外存&#xff0c;如果对磁盘上的数据的位置不加以记录和组织&#xff0c;每查询一个数据项都要扫描整个数据文件&#xff0c;则这种访问磁盘的代价将严…

文件桌面跟计算机同步删除吗,电脑里桌面文件被不慎覆盖了如何恢?

2007-10-30如何恢复桌面图标不小心将某个程序的桌面Windows桌面图标是启动计算机一定程序或文档的开关,Windows桌面的图标分为两类&#xff1a;快捷图标和默认图标。快捷图标主要由应用程序安装时自动创建或计算机使用者人为创建&#xff0c;用一个从左下向右上斜指的小箭头来标…

win10易升_微软Win10版本20H2正式版官方ISO镜像下载大全_windows10_Windows系列_操作系统...

10月21日&#xff0c;微软推送了 Windows 10 十月更新版 20H2 系统更新。我个人认为微软 Win10 版本 20H2 正式版官方 ISO 镜像下载大全&#xff1a;此次系统版本(20H2)更新相对于上一版 20H1 正式版&#xff0c;这次十月更新的 20H2 正式版可能是很棒的一个版本&#xff0c;因…

乐观锁的两种实现方式

什么场景下需要使用锁&#xff1f; 在多节点部署或者多线程执行时&#xff0c;同一个时间可能有多个线程更新相同数据&#xff0c;产生冲突&#xff0c;这就是并发问题。这样的情况下会出现以下问题&#xff1a;更新丢失&#xff1a;一个事务更新数据后&#xff0c;被另一个更新…

c++编译时候fatal error C1075: end of file found before the left brace '{' at

出现 C:\Users\acer\Downloads\Cpp2.cpp(591) : fatal error C1075: end of file found before the left brace { at C:\Users\acer\Downloads\Cpp2.cpp(357) was matched 执行 cl.exe 时出错. 谁知道怎么求改&#xff1f;&#xff1f; 答&#xff1a; 程序中 {} 不是成对出现…

Cloud Foundry Java客户端–流事件

Cloud Foundry Java客户端提供了基于Java的绑定&#xff0c;用于与正在运行的Cloud Foundry实例进行交互。 这个项目的优点之一是它采用了基于Reactive Stream的API作为方法签名&#xff0c;特别是使用Reactor实现&#xff0c;这在使用流数据时特别有用。 在这篇文章中&#x…

vue导入html登陆页,Vue 实现 登陆后打开主页面(登陆组件 + 主页面组件)

本次演示&#xff0c;项目所需iview&#xff0c;router首先在 views 目录 新建 两个 组件 ( login.vue &#xff0c;index.vue )login.vue登录登 录export default {methods: {login() {// 假设登陆成功&#xff0c;则跳转到 index 组件this.$router.replace(/index);}}}backgr…

设置窗口大小

window.resizeTo(screen.availWidth, screen.availHeight);转载于:https://www.cnblogs.com/7q4w1e/p/9680037.html

android IO流_Flutter实战经验(十):打包和发布到 Android 平台

本文适合ios开发者不清楚Android上架机制学习。在一般的开发过程中&#xff0c;我们可以使用 flutter run 命令&#xff0c;或者 IntelliJ 工具栏中的 Run 和 Debug 来测试 app。这时候&#xff0c;Flutter 默认会为我们构建 app 的调试版本。当想要发布 app 时&#xff0c;比如…

西安单招学校学计算机软件的,西北大学软件职业技术学院单招

西北大学肇始于1902年的陕西大学堂和京师大学堂速成科仕学馆&#xff0c;1912年始称西北大学&#xff0c;1978年被确定为全国重点大学。现为国家“211工程”建设院校、教育部与陕西省共建高校。在长期的办学历程中&#xff0c;西北大学形成了“发扬民族精神&#xff0c;融合世界…

autojs遍历当前页面所有控件_PyQT5控件:容器(Containers Widgets)

QWidget主窗体容器 在Qt设计师中新建文件&#xff0c;选择QWidget QWidget属性 enabled 窗口部件是否有效geometry 窗口部件相对于其父窗口的几何图形&#xff0c;并排除窗口框架sizePolicy 窗口部件的默认布局行为minimumSize 窗口部部件的最小尺寸&#xff08;以像素为单位&a…

JAVA 技术类分享(一)

一、dubbo dubbo原理模型&#xff1f; 主要是注册中心&#xff0c;服务提供者&#xff0c;服务消费者&#xff0c;监控中心&#xff0c;其中后者可有可无。1.服务端&#xff0c;在注册中心注册自己提供的服务&#xff0c;并暴露端口&#xff0c;2.客户端在注册中心注册&#xf…

计算机的就业指导论文,计算机就业指导期刊文章参考文献 计算机就业指导专著类参考文献有哪些...

为论文写作提供【100个】计算机就业指导期刊文章参考文献,海量计算机就业指导相关论文参考文献,包括期刊,专著,外文参考文献,解决您的计算机就业指导专著类参考文献有哪些的相关难题&#xff01;一、计算机就业指导论文参考文献范文[1]“基于就业岗位需求”的专业课程体系建设的…

junit rule_使用JUnit的ExpectedException和@Rule测试自定义异常

junit rule异常测试 为什么要测试异常流&#xff1f; 就像所有代码一样&#xff0c;测试覆盖率在代码和应该产生的业务功能之间写了一个合同&#xff0c;从而为您提供了代码的有效文档 &#xff0c;以及可以尽早且经常强调功能的附加功能。 我不会介绍测试的许多好处&#xff0…

经纬度1秒约等于多少米?

WGS84坐标系统下&#xff08;通常我们采用的GPS内的坐标系统&#xff09; 如果是中国常用的WGS1984的经纬度坐标&#xff0c;1秒相当于33米。具体如下&#xff1a; 经度1度85.39km 经度1分 1.42km 经度1秒 23.6m 纬度1度 大约111km 纬度1分 大约1.85km 纬度1秒 大约30.9m

学计算机单招可以报那几个公立学校,为什么要选择公办单招学校,四川公办单招学校有哪些?...

高职单招单招被称为春季高考&#xff0c;在四川参加单招考试的学生逐年上升&#xff0c;周时参加单招的高职院校也越来越多。但是单招不像是高考可以通过不同的志愿&#xff0c;来填报多所学校。单招只能选择某一个学校&#xff0c;一旦确定就不能更改。这样的结果就是选择学校…

AutoValue:生成的不可变值类

Google GitHub托管的项目AutoValue之所以有趣&#xff0c;有多种原因。 该项目不仅使为“ 值对象 ”编写更少的Java代码变得容易&#xff0c;而且还为Java注释处理的实际应用提供了概念上简单的演示。 该自动/值项目是由提供谷歌的员工凯文Bourrillion和埃蒙麦克马纳斯和许可与…

exit(0)与exit(1)、return区别

exit&#xff08;0&#xff09;&#xff1a;正常运行程序并退出程序&#xff1b; exit&#xff08;1&#xff09;&#xff1a;非正常运行导致退出程序&#xff1b; return&#xff08;&#xff09;&#xff1a;返回函数&#xff0c;若在主函数中&#xff0c;则会退出函数并返回…