[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)的抽象类 ...
随机推荐
- ApsNetCore打造一个“最安全”的api接口
Authentication,Authorization 如果公司交给你一个任务让你写一个api接口,那么我们应该如何设计这个api接口来保证这个接口是对外看起来"高大上",&qu ...
- Linear Referencing Tools(线性参考工具)
线性参考工具 # Process: 创建路径 arcpy.CreateRoutes_lr("", "", 输出路径要素类, "LENGTH" ...
- 洛谷3176 [HAOI2015]数字串拆分 (矩阵乘法+dp)
qwq真的是一道好题qwq自己做基本是必不可能做出来的. 首先,如果这个题目只是求一个\(f\)数组的话,那就是一道裸题. 首先,根据样例 根据题目描述,我们能发现其实同样数字的不同排列,也是属于不同 ...
- Python设置Excel样式
前面已经详细讲解过使用Python对Excel表格进行读.写操作,本文主要讲解下使用Python设置Excel表格的样式. 深入学习请参考openpyxl官方文档: https://openpyxl. ...
- SpringCloud微服务实战——搭建企业级开发框架(五):数据库持久化集成MySql+Druid+MyBatis-Plus
在引入相关数据库持久化相关依赖库之前,我们可以考虑到,当我们因业务开发需要,引入各种各样的依赖库时,Jar包冲突是我们必须面对的一个问题,Spring为了解决这些Jar包的冲突,推出了各种bom, ...
- 264.丑数II
题目 给你一个整数 n ,请你找出并返回第 n 个 丑数 . 丑数 就是只包含质因数 2.3 和/或 5 的正整数. 示例 1: 输入:n = 10 输出:12 解释:[1, 2, 3, 4, 5, ...
- Coursera Deep Learning笔记 逻辑回归典型的训练过程
Deep Learning 用逻辑回归训练图片的典型步骤. 笔记摘自:https://xienaoban.github.io/posts/59595.html 1. 处理数据 1.1 向量化(Vect ...
- Java:AQS 小记-1(概述)
Java:AQS 小记-1(概述) 概述 全称是 Abstract Queued Synchronizer(抽象队列同步器),是阻塞式锁和相关的同步器工具的框架,这个类在 java.util.conc ...
- Spring动态添加定时任务
Spring动态添加定时任务 一.背景 二.需求和实现思路 1.能够动态的添加一个定时任务. 2.能够取消定时任务的执行. 3.动态的修改任务执行的时间. 4.获取定时任务执行的异常 三.代码实现 四 ...
- 难搞的C语言指针你搞懂了多少
C语言指针说难不难但是说容易又是最容易出错的地方,因此不管是你要做什么只要用到C指针你就跳不过,今天咱们就以 十九个例子来给大家简单的分析一下指针的应用,最后会有C语言视频资料提供给大家更加深入的参考 ...