[loj6031]字符串
为了方便,用$N=10^{5}$来描述复杂度
(对原串建立SAM)注意到$\sum|w|=qk\le N$,考虑对$q$和$k$的大小关系分类讨论:
1.若$q\le k$,即询问次数较少,将其与原串建立一个广义SAM,然后找到枚举所有区间,倍增找到该区间对应子串的位置,该right集合大小即为答案,时间复杂度为$o(qN\log N)$
(建立广义SAM的实际操作,由于只关心于$s$的子串,并不需要新建节点,会更方便一些)
2.若$k<q$,即串长较短,直接暴力枚举查询串的所有子串,并在原串的SAM上查询其出现次数(即对应节点的right集合大小),然后统计其在$[l_{a},r_{a}],[l_{a+1},r_{a+1}],...,[l_{b},r_{b}]$中出现了几次:
将$m$个区间中相同区间存储位置到同一个vector中,然后即查询该区间对应的vector有几个元素在$[a,b]$中,通过二分即可,时间复杂度为$o(qk^{2}\log N)=o(Nk\log N)$
显然总复杂度为$O(N\sqrt{N}\log N)$,可以通过

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define ll long long
5 vector<int>v[N];
6 int V,n,m,q,l,lst,a,b,nex[N],len[N],R[N],ch[N][26],A[N],B[N],pos[N],Len[N],fa[N][20];
7 ll ans;
8 char s[N],ss[N];
9 void add(int c){
10 int p=lst,np=lst=++V;
11 len[np]=len[p]+1;
12 while ((p)&&(!ch[p][c])){
13 ch[p][c]=np;
14 p=nex[p];
15 }
16 if (!p)nex[np]=1;
17 else{
18 int q=ch[p][c];
19 if (len[q]==len[p]+1)nex[np]=q;
20 else{
21 int nq=++V;
22 nex[nq]=nex[q];
23 nex[q]=nex[np]=nq;
24 len[nq]=len[p]+1;
25 memcpy(ch[nq],ch[q],sizeof(ch[q]));
26 while ((p)&&(ch[p][c]==q)){
27 ch[p][c]=nq;
28 p=nex[p];
29 }
30 }
31 }
32 }
33 void dfs(int k,int f){
34 fa[k][0]=f;
35 for(int i=1;i<20;i++)fa[k][i]=fa[fa[k][i-1]][i-1];
36 for(int i=0;i<v[k].size();i++){
37 dfs(v[k][i],k);
38 R[k]+=R[v[k][i]];
39 }
40 }
41 int get(int k,int l){
42 for(int i=19;i>=0;i--)
43 if (len[fa[k][i]]>=l)k=fa[k][i];
44 return k;
45 }
46 int main(){
47 scanf("%d%d%d%d%s",&n,&m,&q,&l,s);
48 for(int i=0;i<m;i++)scanf("%d%d",&A[i],&B[i]);
49 V=lst=1;
50 for(int i=0;i<n;i++){
51 add(s[i]-'a');
52 R[lst]=1;
53 }
54 for(int i=2;i<=V;i++)v[nex[i]].push_back(i);
55 dfs(1,0);
56 if (q<=l){
57 for(int ii=1;ii<=q;ii++){
58 scanf("%s%d%d",ss,&a,&b);
59 ans=0;
60 for(int i=0,k=1;i<l;i++){
61 while ((k>1)&&(!ch[k][ss[i]-'a']))k=nex[k];
62 Len[i]=len[k];
63 if (i)Len[i]=min(Len[i],Len[i-1]);
64 if (ch[k][ss[i]-'a']){
65 k=ch[k][ss[i]-'a'];
66 Len[i]++;
67 }
68 pos[i]=k;
69 }
70 for(int j=a;j<=b;j++)
71 if (Len[B[j]]>=B[j]-A[j]+1)ans+=R[get(pos[B[j]],B[j]-A[j]+1)];
72 printf("%lld\n",ans);
73 }
74 }
75 else{
76 for(int i=0;i<l*l;i++)v[i].clear();
77 for(int i=0;i<m;i++)v[A[i]*l+B[i]].push_back(i);
78 for(int ii=1;ii<=q;ii++){
79 scanf("%s%d%d",ss,&a,&b);
80 ans=0;
81 for(int i=0;i<l;i++)
82 for(int j=i,k=1;j<l;j++){
83 k=ch[k][ss[j]-'a'];
84 if (!k)break;
85 int p=i*l+j;
86 int posl=lower_bound(v[p].begin(),v[p].end(),a)-v[p].begin();
87 int posr=upper_bound(v[p].begin(),v[p].end(),b)-v[p].begin()-1;
88 ans+=(ll)R[k]*max(posr-posl+1,0);
89 }
90 printf("%lld\n",ans);
91 }
92 }
93 return 0;
94 }
[loj6031]字符串的更多相关文章
- [LOJ6029~6052]雅礼集训 2017 选做
Link 代码可以在loj上看我的提交记录. Day 1 [LOJ6029]市场 对于一次除法操作,若区间内所有数的减少量均相同则可视作区间减法,否则暴力递归下去.显然一个线段树节点只会被暴力递归进去 ...
- loj6031「雅礼集训 2017 Day1」字符串
题目 首先先对\(s\)建一个\(\operatorname{SAM}\),设\(w=kq\) 发现\(k,q\leq 10^5\),但是\(w\leq 10^5\),于是套路地根号讨论一下 如果\( ...
- 并不对劲的Loj6031:「雅礼集训 2017 Day1」字符串
题目传送门:-> 看到题目的第一反应当然是暴力:对于串s建后缀自动机,每次询问中,求w对应的子串在s的SAM中的right集合.O(qmk)听上去显然过不了. 数据范围有个∑w<=1e5, ...
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 测试一下StringBuffer和StringBuilder及字面常量拼接三种字符串的效率
之前一篇里写过字符串常用类的三种方式<java中的字符串相关知识整理>,只不过这个只是分析并不知道他们之间会有多大的区别,或者所谓的StringBuffer能提升多少拼接效率呢?为此写个简 ...
- java中的字符串相关知识整理
字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...
- JavaScript 字符串实用常操纪要
JavaScript 字符串用于存储和处理文本.因此在编写 JS 代码之时她总如影随形,在你处理用户的输入数据的时候,在读取或设置 DOM 对象的属性时,在操作 Cookie 时,在转换各种不同 Da ...
- Java 字符串格式化详解
Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...
- Redis的简单动态字符串实现
Redis 没有直接使用 C 语言传统的字符串表示(以空字符结尾的字符数组,以下简称 C 字符串), 而是自己构建了一种名为简单动态字符串(simple dynamic string,sds)的抽象类 ...
随机推荐
- oracle扩展表空间
1. 查看表空间的名字及文件所在的位置 select tablespace_name, file_id, file_name, round(bytes / (1024 * 1024), 0) tot ...
- vue3 专用 indexedDB 封装库,基于Promise告别回调地狱
IndexedDB 的官网 https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API 这个大概是官网吧,原始是英文的,现在陆续是出中 ...
- Azure Tips 第一期: Azure 中的安全监视工具,数据存储, 动态数据屏蔽以及资源部署
# 1 Azure 中的安全监视工具 微软 Azure 云提供以下监控工具,可用于观察操作和检测异常行为. Azure 安全中心 Azure 安全中心是一个统一的基础结构安全管理系统,可以增强数据中心 ...
- 常用SQL函数大全
数学函数 mod(x,y) 返回x/y的模(余数)mod(5,3)=2,mod(3,5)=3 floor(x) 返回小于x的最大整数值ceiling(3)=3,ceiling(3.1)=3 cei ...
- Python中生成器的理解
1.生成器的定义 在Python中一边循环一边计算的机制,称为生成器 2.为什么要有生成器 列表所有的数据都存在内存中,如果有海量的数据将非常耗内存 如:仅仅需要访问前面几个元素,那后面绝大多数元素占 ...
- iostream 操作符
iostream 操作符 Input/output manipulators - cppreference.com
- 手把手教你写hexo博客
市面上现在有各种博客框架,本博客教大家的是Hexo博客框架,目前比较火.搭建博客中遇到各种各样问题,网上方案也比较成熟. 一.搭建环境 安装 git 安装 node.js 安装 Hexo npm in ...
- python常用功能
1. 获取昨天日期 引入datetime模块 import datetime def getYesterday(): today = datetime.date.today() #返回当前本地日期 # ...
- 初学python-day5 流程控制
流程控制 一.判断语句 1.if语句(单一条件分支) 结构: if 表达式: 为真的时候执行的语句 概述:当程序运行到if语句时候,首页要计算表达式的值,判断真假,如果表达式的职位为真,则执行i ...
- BUAA软工-结对项目作业
结对项目作业 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 结对项目作业 我在这个课程的目标是 通过这门课锻炼软件开发能力和经验,强化与他人合作 ...