题目

给定一个长度为\(n\)的串,定义两个串匹配当且仅当两个串长度相同并且不同字符至多一个

对于每一个长度为\(m\)的子串输出和它匹配的子串个数

$1 \le n \le 10^5 \ , \ m \le n $ 字符集=4

题解

  • 我不知道字符集为什么等于4..
  • 匹配的条件相当于$lcp+lcs \ge m-1 $
  • 正反建\(SA\),倒着枚举\(lcp\)的值,相当于合并\(suffix\)
  • 要求合法的\(lcs\)大于等于\(m-1-lcp\),每次合并在\(preffix\)上二分贡献答案
  • 用线段树维护答案
  • 实现可以启发式+线段树合并
  • 时间复杂度 \(O(n \ log ^2n)\)
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define il inline using namespace std; const int N=100010,M=200;
int n,m,bin[17],sum[N*M],add[N*M],ls[N*M],rs[N*M],fa[N],sz[N],cnt,st[N],rt[N],lg[N];
vector<int>vec[N];
char s[N];
ll ans[N]; struct SA{
int sa[N],rk[N],ht[N],f[N][17];
void init(){
//printf("%s\n",s);
build_sa();
//for(int i=0;i<n;++i)printf("% 2d",sa[i]);puts("");
build_ht();
//for(int i=0;i<n;++i)printf("% 2d",ht[i]);puts("");
build_rmq();
}
void build_sa(){
int m=128;
static int x[N],y[N],c[N];
for(int i=0;i<m;++i)c[i]=0;
for(int i=0;i<n;++i)c[x[i]=s[i]]++;
for(int i=1;i<m;++i)c[i]+=c[i-1];
for(int i=n-1;~i;--i)sa[--c[x[i]]]=i;
for(int k=1,p=0;k<n&&p<n;k<<=1,m=p){
p=0;for(int j=n-k;j<n;++j)y[p++]=j;
for(int i=0;i<n;++i)if(sa[i]>=k)y[p++]=sa[i]-k;
for(int i=0;i<m;++i)c[i]=0;
for(int i=0;i<n;++i)c[x[i]]++;
for(int i=1;i<m;++i)c[i]+=c[i-1];
for(int i=n-1;~i;--i)sa[--c[x[y[i]]]]=y[i];
p=1;swap(x,y);x[sa[0]]=0;
for(int i=1;i<n;++i){
x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++;
}
}
}
void build_ht(){
for(int i=0;i<n;++i)rk[sa[i]]=i;
for(int i=0,j=0,k=0;i<n-1;ht[rk[i++]]=k){
j=sa[rk[i]-1];if(k)k--;
while(s[j+k]==s[i+k])++k;
}
}
il int min(int x,int y){if(x<y)return x;return y;}
void build_rmq(){
for(int i=1;i<n;++i)f[i][0]=ht[i];
for(int i=1;i<17;++i)
for(int j=1;j+bin[i]-1<n;++j){
f[j][i]=min(f[j][i-1],f[j+bin[i-1]][i-1]);
}
}
il int ask(int l,int r){
if(l==r)return n+1;
int t=lg[r-l];
return min(f[l+1][t],f[r-bin[t]+1][t]);
}
void find(int x,int y,int&L,int&R){
x=rk[x];
int l=0,r=x;
while(l<r){
int mid=(l+r)>>1;
if(ask(mid,x)>=y)r=mid;
else l=mid+1;
}L=l;
l=x,r=n;
while(l<r){
int mid=(l+r+1)>>1;
if(ask(x,mid)>=y)l=mid;
else r=mid-1;
}R=r;
}
}pre,suf;
bool cmp(int a,int b){return suf.ht[a]<suf.ht[b];} void pushdown(int k){
int l=ls[k],r=rs[k];
if(l)add[l]+=add[k];
if(r)add[r]+=add[k];
add[k]=0;
}
void ins(int&k,int l,int r,int x){
sum[k=++cnt]++;
if(l==r)return;
int mid=(l+r)>>1;
if(x<=mid)ins(ls[k],l,mid,x);
else ins(rs[k],mid+1,r,x);
}
int modify(int k,int l,int r,int x,int y){
if(!k)return 0;
if(l==x&&r==y){add[k]++;return sum[k];}
int mid=(l+r)>>1;
if(y<=mid)return modify(ls[k],l,mid,x,y);
else if(x>mid)return modify(rs[k],mid+1,r,x,y);
else return modify(ls[k],l,mid,x,mid)+modify(rs[k],mid+1,r,mid+1,y);
}
void getans(int k,int l,int r){
if(!k)return;
if(l==r){
ans[n-m-pre.sa[l]]+=add[k];
return;
}
if(add[k])pushdown(k);
int mid=(l+r)>>1;
getans(ls[k],l,mid);
getans(rs[k],mid+1,r);
}
int merge(int x,int y){
if(!x||!y)return x+y;
if(add[x])pushdown(x);
if(add[y])pushdown(y);
sum[x]+=sum[y];
ls[x]=merge(ls[x],ls[y]);
rs[x]=merge(rs[x],rs[y]);
return x;
} int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void comb(int x,int y,int lim){
x=find(x),y=find(y);
if(sz[x]>sz[y])swap(x,y);
for(int i=0,l,r;i<(int)vec[x].size();++i){
int t=vec[x][i];vec[y].pb(t);
if(t>n-m)continue;
pre.find(n-m-t,lim,l,r);
ans[t]+=modify(rt[y],0,n,l,r);
}
rt[y]=merge(rt[x],rt[y]);
fa[x]=y;sz[y]+=sz[x];
} int main(){
freopen("lovely.in","r",stdin);
freopen("lovely.out","w",stdout);
scanf("%d%d%s",&n,&m,s);
for(int i=bin[0]=1;i<17;++i)bin[i]=bin[i-1]<<1;
for(int i=2;i<=n;++i)lg[i]=lg[i>>1]+1;
s[n++]='$';suf.init();
reverse(s,s+n-1);pre.init();
n--;
for(int i=0;i<n;++i){
fa[i]=i;sz[i]=1;vec[i].pb(i);
if(i>n-m)continue;
ins(rt[i],0,n,pre.rk[n-m-i]);
}
for(int i=2;i<=n;++i)st[i]=i;
sort(st+2,st+n+1,cmp);
for(int i=m-1,j=n;~i;--i){
while(j>1&&suf.ht[st[j]]>=i){
int x=st[j--],y=x-1;
comb(suf.sa[x],suf.sa[y],m-1-i);
}
}
getans(rt[find(0)],0,n);
for(int i=0;i<=n-m;++i)printf("%lld ",ans[i]);
return 0;
}

【JZOJ6222】【20190617】可爱的更多相关文章

  1. 可爱的豆子——使用Beans思想让Python代码更易维护

    title: 可爱的豆子--使用Beans思想让Python代码更易维护 toc: false comments: true date: 2016-06-19 21:43:33 tags: [Pyth ...

  2. 用3D再现2D偶像的可爱,Cygames【偶像大师 灰姑娘女孩】开发示例

          作为万代南梦宫娱乐的偶像养成游戏[偶像大师]的派生作品,是由Mobage创作的[偶像大师 灰姑娘女孩].这个游戏的最新作品,是现在累计下载突破1200万的大作,Android/iOS平台的 ...

  3. 【偶像大师 白金星光】的【Variable Tone】技术大公开!偶像从哪里看都那么可爱,VA小组谈制作方针

    http://game.watch.impress.co.jp/docs/news/1016369.html         自从街机版的运营依赖,今年迎来了[偶像大师]系列的11周年.在CEDEC ...

  4. 太可爱了!CSS3 & SVG 制作的米老鼠钟表

    米老鼠是大家非常熟悉的迪斯尼动画形象.这是一个可爱的效果,结合 CSS & SVG 图形实现的米老鼠钟表效果.Web 技术让很多生活中的事物都能搬到网上去,后面的推荐阅读也有很多的效果,感兴趣 ...

  5. jQuery.swatches – 把 Div 变成可爱的调色板

    jQuery.swatches 是一款开源的 jQuery 插件,能够把一个 Div 转换成漂亮的调色板.您可以自定义你想要的类,使用不同的类可以生成不同的调色板.这个功能能够帮助设计师方便的挑选设计 ...

  6. Hello Kitty微信主题很可爱?小心财产安全!

    个性化是产品服务的一个趋势.微信很火,可为什么微信主题只有一个呢?你让那些小女生情何以堪?这时HelloKitty微信主题.大嘴猴.哆啦A梦等一大批主题在网上出现了,有些打着免费的旗号却做着盗号的勾当 ...

  7. 8款给力HTML5/CSS3应用插件 可爱的HTML5笑脸

    1.HTML5/CSS3实现笑脸动画 非常可爱 今天我们要分享一款基于纯CSS3实现的笑脸动画,我们只要在面部滑动鼠标,即可让人物的眼睛嘴巴动起来,实现微笑的效果,还挺可爱的. 在线演示 源码下载 2 ...

  8. 洛谷 P1428 小鱼比可爱

    题目描述 人比人,气死人:鱼比鱼,难死鱼.小鱼最近参加了一个“比可爱”比赛,比的是每只鱼的可爱程度.参赛的鱼被从左到右排成一排,头都朝向左边,然后每只鱼会得到一个整数数值,表示这只鱼的可爱程度,很显然 ...

  9. COJ 0650 绝世难题(一) 可爱的仙人掌

    传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=620 绝世难题(一) 可爱的仙人掌 难度级别:E: 运行时间限制:1000m ...

随机推荐

  1. mysql 5.7 非正常安装,无法启动 服务没有报告任何错误

    以前,完整安装mysql5.7程序时,由于程序太大,可以将安装缓存目录中的安装文件(较小)复制出来后,留以后使用. mysql--win32.msi 2 mysql-5.7.17-winx64.msi ...

  2. MVC的Views中使用递归生成Html【转】

    在开发过程中往往会有一个需求,就是将一个树状的数据结构在视图中表示出来.例如最传统的多级分类,系统中有一系列根分类,每个分类中又带有一些子分类,而我们的目标便是在页面上生成一个由ul和li嵌套组成的H ...

  3. js调用浏览器下载

    $scope.Download = function (url) { var save_link = document.createElementNS("http://www.w3.org/ ...

  4. MongoDB和Java(5):Spring Data整合MongoDB(注解配置)

    最近花了一些时间学习了下MongoDB数据库,感觉还是比较全面系统的,涉及了软件安装.客户端操作.安全认证.副本集和分布式集群搭建,以及使用Spring Data连接MongoDB进行数据操作,收获很 ...

  5. 2019 4399java面试笔试题 (含面试题解析)

    本人3年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.4399等公司offer,岗位是Java后端开发,最终选择去了4399. 面试了很多家公司,感觉大部分公司考察的点 ...

  6. 解决vue-cli项目开发中跨域问题

    一.开发环境中跨域 使用 Vue-cli 创建的项目,开发地址是 localhost:8080,需要访问非本机上的接口http://10.1.0.34:8000/queryRole.不同域名之间的访问 ...

  7. HTTP协议学习总结

    一个web应用程序,往往是通过http协议进行前后端通信的.而作为一个web工程师,掌握HTTP协议因此也是Web开发必备的一项技能了,尤其是在工作了一定年限之后,更是深感该知识点的重要性.因此,将以 ...

  8. DB2数据库中DB2字符串类型

    DB2字符串是DB2数据库中的基础知识,下面就为您分类介绍DB2字符串,供您参考,如果您对DB2字符串方面刚兴趣的话,不妨一看. DB2字符串是字节序列.DB2字符串包括 CHAR(n) 类型的定长字 ...

  9. 【OGG】OGG简单配置双向复制(三)

    [OGG]OGG简单配置双向复制(三) 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O ...

  10. SpringCloud-Zuul源码分析和路由改造

    在使用SpringCloud的时候准备使用Zuul作为微服务的网关,Zuul的默认路由方式主要是两种,一种是在配置 文件里直接指定静态路由,另一种是根据注册在Eureka的服务名自动匹配.比如如果有一 ...