【LGP5112】FZOUTSY
如果是\(hash\)做法的话显然就是把每一个位置后面的\(k\)个位置的hash值拿出来做一个莫队板子就好了
考虑一下牛逼的\(SAM\)
我们完全可以构造出来一棵后缀树,对于每个点找到其祖先里深度最小且\(len<=k\)的一个点,我们莫队一下就好了
最优分块大小是\(\frac{n}{\sqrt{m}}\),这样复杂度是\(O(n\sqrt{m})\)
代码
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int maxn=6000005;
struct Ask{int l,r,rk;}q[100005];
int n,m,k,lst=1,cnt=1;LL ans;
char S[maxn>>1];
int g[maxn],h[maxn],son[maxn][7],len[maxn],pos[maxn>>1],fa[maxn],tmp[maxn];
int tax[maxn>>1],A[maxn],id[maxn>>1];LL Ans[100005];
inline void ins(int c,int o) {
int p=++cnt,f=lst;lst=p;
len[p]=len[f]+1,pos[o]=p;
while(f&&!son[f][c]) son[f][c]=p,f=fa[f];
if(!f) {fa[p]=1;return;}
int x=son[f][c];
if(len[f]+1==len[x]) {fa[p]=x;return;}
int y=++cnt;
len[y]=len[f]+1,fa[y]=fa[x],fa[x]=fa[p]=y;
for(re int i=0;i<7;i++) son[y][i]=son[x][i];
while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];
}
inline int chk(char x) {
if(x=='f') return 0;if(x=='z') return 1;
if(x=='o') return 2;if(x=='u') return 3;
if(x=='t') return 4;if(x=='s') return 5;
return 6;
}
inline void add(int x) {
if(!h[pos[x]]) return;
ans+=tmp[h[pos[x]]];++tmp[h[pos[x]]];
}
inline void del(int x) {
if(!h[pos[x]]) return;
--tmp[h[pos[x]]];ans-=tmp[h[pos[x]]];
}
inline int cmp(Ask A,Ask B) {return id[A.l]==id[B.l]?A.r<B.r:id[A.l]<id[B.l];}
int main() {
n=read(),m=read(),k=read();scanf("%s",S+1);
for(re int i=1;i<=n;i++) S[i]=chk(S[i]);
for(re int i=n;i;--i) ins(S[i],i);
for(re int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].rk=i;
int sz=n/(std::sqrt(m)+1);int L=1,tot=1;
while(L<=n) {for(re int i=L;i<=min(L+sz-1,n);i++) id[i]=tot;L+=sz,++tot;}
std::sort(q+1,q+m+1,cmp);
for(re int i=2;i<=cnt;i++) if(len[i]>=k&&len[fa[i]]<k) g[i]=1;
for(re int i=1;i<=cnt;i++) tax[len[i]]++;
for(re int i=1;i<=n;i++) tax[i]+=tax[i-1];
for(re int i=cnt;i;--i) A[tax[len[i]]--]=i;
for(re int i=1;i<=cnt;i++) {
int x=A[i];
if(g[x]) h[x]=x;else h[x]=h[fa[x]];
}
int l=0,r=0;
for(re int i=1;i<=m;i++) {
while(r<q[i].r) add(++r);
while(l<q[i].l) del(l++);
while(l>q[i].l) add(--l);
while(r>q[i].r) del(r--);
Ans[q[i].rk]=ans;
}
for(re int i=1;i<=m;i++) printf("%lld\n",Ans[i]);
return 0;
}
【LGP5112】FZOUTSY的更多相关文章
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 【原】谈谈对Objective-C中代理模式的误解
[原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【调侃】IOC前世今生
前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...
- Python高手之路【三】python基础之函数
基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...
- Python高手之路【一】初识python
Python简介 1:Python的创始人 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种解释型.面向对象.动态数据类型的高级程序设计语言,由荷兰人Guido ...
- 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】
说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...
- 【原】FMDB源码阅读(二)
[原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...
随机推荐
- windows下执行tensorflow/models的代码显示No module named 'object_detection'
Traceback (most recent call last): File "object_detection/builders/model_builder_test.py", ...
- split的用法
split用法返回的是数组 使用split('')根据空格返回数组 使用split()返回一个完整的数组 使用split("",3)返回前三项,是单个的字母 不过要注意: 使用sp ...
- delphi 第3课
(1)主程序:汇总或者记载 Delphi应用程序是以窗体为中心的 (1) 1 (2) 控制语句 if 条件 then 语句1: else 语句2: 2018-04-22 21:47:17
- javascript中onclick(this)用法和onclick(this.value)用法介绍
onclick(this.value)代码详解 <html> <head> <script language="javascript"> fun ...
- ubuntu 没有桌面 没有图标,只剩下壁纸
sudo apt-get update sudo apt-get install --reinstall ubuntu-desktop sudo apt-get install unity sudo ...
- Mac 上的 redis
Mac下添加redis的环境变量: echo 'export PATH="/usr/local/opt/redis@3.2/bin:$PATH"' >> ~/.bash ...
- css实现文字内容超出显示省略号
white-space: nowrap; /* 内容超出容器宽度时强制不换行 */ overflow: hidden; /* 内容超出容器时隐藏超出部分 */ text-overflow: ellip ...
- Identifying a Blocking Query After the Issuing Session Becomes Idle
Identifying a Blocking Query After the Issuing Session Becomes Idle #查看阻塞信息 select * from sys.innodb ...
- 普及组R4
T3 链接:C 输入一个长度为n的数组a[i],下标从0开始(0到n-1) 保证n是2的整数次幂, 对于每个i (0 <= i < n) 求所有满足((i & j) == j)的a ...
- Mid-Atlantic 2008 Lawrence of Arabia /// 区间DP oj21080
题目大意: 输入n,m 输入n个数 将n个数切割m次分为m+1段,使得各段的Strategic Value总和最小 一组数a b c d的SV值为 a*b + a*c + a*d + b*c + b* ...