【BZOJ3413】匹配 离线+后缀树+树状数组
【BZOJ3413】匹配
Description
.jpg)
Input
第一行包含一个整数n(≤100000)。
第二行是长度为n的由0到9组成的字符串。
第三行是一个整数m。
接下来m≤5·10行,第i行是一个由0到9组成的字符串s,保证单行字符串长度小于等于10^5,所有字符串长度和小于等于3·10^6
Output
输出m行,第i行表示第si和S匹配所比较的次数。
Sample Input
1090901
4
87650
0901
109
090
Sample Output
10
3
4
题解:题目是问你截止到匹配之前,A串的每个位置与B串的LCP+1之和。这要利用到一个性质,两个后缀的lcp长度等于后缀树上两个点的lca的mx值。所以我们对A串的反串建立后缀自动机,得到后缀树,然后将B串放到后缀树中进行匹配(后缀树中匹配不同于后缀自动机中的匹配,实现比较复杂,方法也有很多,可以看代码)。如果没有成功匹配,则我们取最后一个成功匹配的节点,从这个点沿着到根的路径一路走上去跑一个树形DP即可。如果匹配成功,我们记录一下匹配成功的节点以及匹配位置,然后离线处理。我们将原串中的点一个一个加到后缀树中去,用树状数组维护DFS序得到子树和,处理询问时依旧跑类似于树形DP的东西即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int N=200010; int n,m,tot,last,cnt;
char S[N],T[N];
int ch[N][10],mx[N],pre[N],p1[N],p2[N],mn[N],pos[N],qos[N],len[N],s[N],L[N],R[N],son[N][10],siz[N];
vector<int> q[N];
vector<int>::iterator it;
int f[N];
ll ans[N];
inline int extend(int x)
{
int p=last,np=++tot; last=np;
mx[np]=mx[p]+1,siz[np]=1;
for(;p&&!ch[p][x];p=pre[p]) ch[p][x]=np;
if(!p) ch[1][x]=np,pre[np]=1;
else
{
int q=ch[p][x];
if(mx[q]==mx[p]+1) pre[np]=q;
else
{
int nq=++tot; mx[nq]=mx[p]+1,R[nq]=R[q]-(mx[q]-mx[p]-1);
pre[nq]=pre[q],pre[np]=pre[q]=nq;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
for(;p&&ch[p][x]==q;p=pre[p]) ch[p][x]=nq;
}
}
return np;
}
void dfs(int x)
{
p1[x]=++p2[0];
for(int i=0,y;i<10;i++) if((y=son[x][i])) dfs(y),siz[x]+=siz[y],mn[x]=min(mn[x],mn[y]);
p2[x]=p2[0];
}
inline void updata(int x)
{
for(int i=x;i<=tot;i+=i&-i) s[i]++;
}
inline int query(int x)
{
int ret=0,i;
for(i=x;i;i-=i&-i) ret+=s[i];
return ret;
}
int main()
{
scanf("%d%s",&n,S);
int i,j,x,y;
memset(mn,0x3f,sizeof(mn));
tot=last=1;
for(i=n-1;i>=0;i--) pos[i]=extend(S[i]-'0'),mn[pos[i]]=i,R[pos[i]]=n-1;
for(i=2;i<=tot;i++) L[i]=R[i]-(mx[i]-mx[pre[i]])+1,son[pre[i]][S[L[i]]-'0']=i;
scanf("%d",&m);
dfs(1);
R[1]=-1;
for(i=1;i<=m;i++)
{
scanf("%s",T),len[i]=strlen(T);
for(x=1,j=y=0;j<len[i];j++)
{
if(y<=R[x])
{
if(S[y]==T[j]) y++;
else break;
}
else
{
if(son[x][T[j]-'0']) x=son[x][T[j]-'0'],y=L[x]+1;
else break;
}
}
qos[i]=x;
if(j<len[i])
{
if(x==1) ans[i]=n;
else
{
ans[i]=n+1ll*siz[x]*min(mx[x]-mx[pre[x]],y-L[x]);
for(x=pre[x];x!=1;x=pre[x]) ans[i]+=1ll*(mx[x]-mx[pre[x]])*siz[x];
}
}
else
{
ans[i]=len[i]+mn[x];
if(mn[x]) q[mn[x]-1].push_back(i);
}
}
for(i=0;i<n;i++)
{
updata(p1[pos[i]]);
for(it=q[i].begin();it!=q[i].end();it++)
{
for(j=pre[qos[*it]];j;j=pre[j]) ans[*it]+=1ll*(mx[j]-mx[pre[j]])*(query(p2[j])-query(p1[j]-1));
}
}
for(i=1;i<=m;i++) printf("%lld\n",ans[i]);
return 0;
}
【BZOJ3413】匹配 离线+后缀树+树状数组的更多相关文章
- BZOJ3413: 匹配(后缀自动机,Parent树,线段树合并)
Description Input 第一行包含一个整数n(≤100000). 第二行是长度为n的由0到9组成的字符串. 第三行是一个整数m. 接下来m≤5·10行,第i行是一个由0到9组成的字符串s, ...
- CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)
The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...
- 【loj6041】「雅礼集训 2017 Day7」事情的相似度 后缀自动机+STL-set+启发式合并+离线+扫描线+树状数组
题目描述 给你一个长度为 $n$ 的01串,$m$ 次询问,每次询问给出 $l$ .$r$ ,求从 $[l,r]$ 中选出两个不同的前缀的最长公共后缀长度的最大值. $n,m\le 10^5$ 题解 ...
- BZOJ 2780 Sevenk Love Oimaster (后缀自动机+树状数组+dfs序+离线)
题目大意: 给你$n$个大串和$m$个询问,每次给出一个字符串$s$询问在多少个大串中出现过 好神的一道题 对$n$个大串建出广义$SAM$,建出$parent$树 把字符串$s$放到$SAM$里跑, ...
- Sereja and Brackets CodeForces - 380C (树状数组+离线)
Sereja and Brackets 题目链接: CodeForces - 380C Sereja has a bracket sequence s1, s2, ..., *s**n, or, in ...
- bzoj2743离线+树状数组
奇葩染色,对于每一个点关心的是前前个同颜色的位置,但是处理方法相同 离线比较神奇,按照右端点排序,然后每次用的是左端点,就不用建可持久化树状数组(什么鬼)了 区间修改+单点查询 果断差分以后用树状数组 ...
- BZOJ1878: [SDOI2009]HH的项链[树状数组 离线]
1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 3486 Solved: 1738[Submit][Statu ...
- HDU 4605 Magic Ball Game (dfs+离线树状数组)
题意:给你一颗有根树,它的孩子要么只有两个,要么没有,且每个点都有一个权值w. 接着给你一个权值为x的球,它从更节点开始向下掉,有三种情况 x=w[now]:停在此点 x<w[now]:当有孩子 ...
- HDU3333 Turing Tree 树状数组+离线处理
Turing Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
随机推荐
- service citrix xcenserver health check service (xenserver healthcheck) failed to start verfy that you have sufficient privileges to srart system services
citrix XcenServer版本:7.2 citrix Xcencenter版本:7.2 安装citrix Xcencenter的时候报错: service citrix xcenserver ...
- vue父组件向子组件动态传值的两种方法
在一些项目需求中需要父组件向子组件动态传值,比如我这里的需求是,父组件动态通过axios获取返回的图片url数组然后传给子组件,上传图片的子组件拿到该数组后进行遍历并展示图片,因为有时候获取到的会是空 ...
- 在 ubuntu 【6.06、6.10】 上安装 oracle 10.2.0.1,并打补丁 10.2.0.5
特点: ubuntu 6.06.6.10 算是很古老的ubuntu了,其应该是基于 debian 4 的 tesing/unstable 分支.所以,毛病较多. 如何安装oracle10g? 几个技术 ...
- IBM Personal Communications 软件:精简绿色版TN3270终端模拟器:经测试可以在 (winxp、win2003、win764)上运行
全系列版本啊!耗费了我大量的时间和精力,深夜熬到3点! 注意:如何使用?解压后,里面有个reg注册表文件,以管理员权限用户双击加载即可. http://files.cnblogs.com/files/ ...
- 找不到 android-support-v4 解决办法
Project->properties->Java Build Path->Libraries->Add External Jars中加入sdk目录下的extras/andro ...
- 安装程序配置服务器失败。参考服务器错误日志和C:\windows\sqlstp.log 了解更多信息
重装sql经常遇到2个问题 1,以前的某个程序安装已在安装计算机上创建挂起的文件操作.运行安装程序之前必须重新启动计算机. 删除C:\Program Files\Microsoft SQL Serve ...
- android studio 导入第三方库的记录
android studio 导入第三方库的记录.jar包 和 库 一.jar包 1.jar包的话很简单,首先换成project模式,将你要用的jar包复制到lib下面.如图 2.然后右键选择Add ...
- Lambda模式
Class TestPatterns '<<1.Self-Defining Functions-自定义函数>> Public Shared Sub SelfDefining() ...
- Dubbo -- 系统学习 笔记 -- 示例 -- 线程模型
Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 线程模型 事件处理线程说明 如果事件处理的逻辑能迅速完成,并且不会发起新的IO请求 ...
- express不是内部或外部命令,也不是可运行的程序或批处理文件
如上安装了express以后,仍然报如下错误:express不是内部或外部命令,也不是可运行的程序或批处理文件 原因是版本问题:当前版本是4.0.0,改成3.5.0即可运行. npm install ...