[LOJ 6031] 「雅礼集训 2017 Day1」字符串

题意

给定一个长度为 \(n\) 的字符串 \(s\), \(m\) 对 \((l_i,r_i)\), 回答 \(q\) 个询问. 每个询问会给定一个长度为 \(k\) 的字符串 \(w\) 以及一对 \(L,R\), 求所有满足 \(i\in [L,R]\) 的 \(w[l_i:r_i]\) 在 \(s\) 中的出现次数之和.

\(n,m,k,q\le 1\times 10^5\), \(\sum |w|\le 1\times 10^5\).

题解

这sb题直接SAM暴力tm有90分...然而考场上把 \(k\) 和 \(q\) 读反了挂成10分...

那个 \(\sum |w|\) 显然就是 \(kq\), 于是 \(kq\le1\times 10^5\). 我们一点都不自然地想到可以根号分类.

当 \(k\le \sqrt m\) 的时候, 显然 \(k^2q=O(m)k=O(m\sqrt m)\). 那么我们直接枚举 \(w\) 的所有子串, 在 \(s\) 的SAM上倍增计算答案, 二分计算当前查询区间中有多少个当前子串就可以统计当前子串对答案的贡献了. 时间复杂度是 \(O(k^2q\log n)=O(m\sqrt m\log n)\).

当 \(k>\sqrt m\) 的时候, 显然 \(kq=O(m)\Rightarrow q=O(\sqrt m)\). 于是我们将所有 \((l_i,r_i)\) 分布到 \(r_i\) 上, 然后边在SAM上跑边计算右端点为当前位置的子串对答案的贡献. 一次的复杂度是 \(O(k+m\log n)\). 总复杂度显然是 \(O(m\sqrt m \log n)\).

然后就过了...

参考代码

#include <bits/stdc++.h>

namespace rvalue{
const int MAXN=2e5+10;
typedef long long intEx; int n;
int q;
int k;
int m;
int lg;
int cnt=1;
int last=1;
int root=1;
int s[MAXN];
int prt[MAXN];
int len[MAXN];
int size[MAXN];
char buf[MAXN];
int pprt[20][MAXN];
std::map<char,int> chd[MAXN]; void Extend(char); namespace BF1{
const int SQRN=350; std::vector<int> qpos[SQRN][SQRN]; int main(){
#ifdef IRECT
puts("BF1");
#endif
for(int i=0;i<m;i++){
int l,r;
scanf("%d%d",&l,&r);
qpos[l][r].push_back(i);
}
while(q--){
int a,b;
scanf("%s%d%d",buf,&a,&b);
int cur=root,curlen=0;
intEx ans=0;
for(int i=0;i<k;i++){
while(cur!=root&&!chd[cur].count(buf[i])){
cur=prt[cur];
curlen=std::min(curlen,len[cur]);
}
if(chd[cur].count(buf[i])){
cur=chd[cur][buf[i]];
++curlen;
int pos=cur;
for(int plen=curlen;plen>=1;plen--){
while(len[prt[pos]]>=plen)
pos=prt[pos];
auto& q=qpos[i-plen+1][i];
auto low=std::lower_bound(q.begin(),q.end(),a);
auto up=std::upper_bound(q.begin(),q.end(),b);
int cnt=up-low;
// printf("%d len=%d cnt=%d\n",i,plen,cnt);
ans+=1ll*cnt*size[pos];
}
}
}
printf("%lld\n",ans);
}
return 0;
}
} namespace BF2{
std::vector<std::pair<int,int>> qlen[MAXN]; int main(){
#ifdef IRECT
puts("BF2");
#endif
for(int i=0;i<m;i++){
int l,r;
scanf("%d%d",&l,&r);
qlen[r].emplace_back(r-l+1,i);
}
while(q--){
int a,b;
scanf("%s%d%d",buf,&a,&b);
int cur=root,curlen=0;
intEx ans=0;
for(int i=0;i<k;i++){
while(cur!=root&&!chd[cur].count(buf[i])){
cur=prt[cur];
curlen=std::min(curlen,len[cur]);
}
if(chd[cur].count(buf[i])){
cur=chd[cur][buf[i]];
++curlen;
for(auto q:qlen[i]){
if(q.second<a||q.second>b)
continue;
if(curlen<q.first)
continue;
int pos=cur;
for(int j=lg;j>=0;j--)
if(len[pprt[j][pos]]>=q.first)
pos=pprt[j][pos];
ans+=size[pos];
}
}
}
printf("%lld\n",ans);
}
return 0;
}
} int main(){
scanf("%d%d%d%d",&n,&m,&q,&k);
scanf("%s",buf);
for(int i=0;i<n;i++)
Extend(buf[i]);
for(int i=1;i<=cnt;i++)
s[i]=i;
std::sort(s+1,s+cnt+1,[](int a,int b){return len[a]>len[b];});
for(int i=1;i<=cnt;i++){
size[prt[s[i]]]+=size[s[i]];
pprt[0][i]=prt[i];
}
for(int j=1;(1<<j)<=cnt;j++){
lg=j;
for(int i=1;i<=cnt;i++)
pprt[j][i]=pprt[j-1][pprt[j-1][i]];
}
if(1ll*k*k<=m)
BF1::main();
else
BF2::main();
return 0;
} void Extend(char x){
int p=last;
int np=++cnt;
size[last=np]=1;
len[np]=len[p]+1;
while(p&&!chd[p].count(x))
chd[p][x]=np,p=prt[p];
if(!p)
prt[np]=root;
else{
int q=chd[p][x];
if(len[q]==len[p]+1)
prt[np]=q;
else{
int nq=++cnt;
len[nq]=len[p]+1;
chd[nq]=chd[q];
prt[nq]=prt[q];
prt[q]=nq;
prt[np]=nq;
while(p&&chd[p][x]==q)
chd[p][x]=nq,p=prt[p];
}
}
}
} int main(){
#if 0
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);
#endif
rvalue::main();
return 0;
}

[LOJ 6031]「雅礼集训 2017 Day1」字符串的更多相关文章

  1. loj 6031「雅礼集训 2017 Day1」字符串

    loj 注意到每次询问串长度都是给定的,并且询问串长\(k*\)询问次数\(q<10^5\),所以这里面一个东西大的时候另一个东西就小,那么考虑对较小的下功夫 如果\(k\le \sqrt{n} ...

  2. loj#6031. 「雅礼集训 2017 Day1」字符串(SAM 广义SAM 数据分治)

    题意 链接 Sol \(10^5\)次询问每次询问\(10^5\)个区间..这种题第一感觉就是根号/数据分治的模型. \(K\)是个定值这个很关键. 考虑\(K\)比较小的情况,可以直接暴力建SAM, ...

  3. [LOJ 6030]「雅礼集训 2017 Day1」矩阵

    [LOJ 6030] 「雅礼集训 2017 Day1」矩阵 题意 给定一个 \(n\times n\) 的 01 矩阵, 每次操作可以将一行转置后赋值给某一列, 问最少几次操作能让矩阵全为 1. 无解 ...

  4. [LOJ 6029]「雅礼集训 2017 Day1」市场

    [LOJ 6029] 「雅礼集训 2017 Day1」市场 题意 给定一个长度为 \(n\) 的数列(从 \(0\) 开始标号), 要求执行 \(q\) 次操作, 每次操作为如下四种操作之一: 1 l ...

  5. loj#6030. 「雅礼集训 2017 Day1」矩阵(贪心 构造)

    题意 链接 Sol 自己都不知道自己怎么做出来的系列 不难观察出几个性质: 最优策略一定是先把某一行弄黑,然后再用这一行去覆盖不是全黑的列 无解当且仅当无黑色.否则第一个黑色所在的行\(i\)可以先把 ...

  6. loj#6029. 「雅礼集训 2017 Day1」市场(线段树)

    题意 链接 Sol 势能分析. 除法是不能打标记的,所以只能暴力递归.这里我们加一个剪枝:如果区间内最大最小值的改变量都相同的话,就变成区间减. 这样复杂度是\((n + mlogn) logV\)的 ...

  7. LOJ #6029. 「雅礼集训 2017 Day1」市场 线段树维护区间除法

    题目描述 从前有一个贸易市场,在一位执政官到来之前都是非常繁荣的,自从他来了之后,发布了一系列奇怪的政令,导致贸易市场的衰落. 有 \(n\) 个商贩,从\(0 \sim n - 1\) 编号,每个商 ...

  8. 「雅礼集训 2017 Day1」字符串 SAM、根号分治

    LOJ 注意到\(qk \leq 10^5\),我们很不自然地考虑根号分治: 当\(k > \sqrt{10^5}\),此时\(q\)比较小,与\(qm\)相关的算法比较适合.对串\(s\)建S ...

  9. 并不对劲的Loj6031:「雅礼集训 2017 Day1」字符串

    题目传送门:-> 看到题目的第一反应当然是暴力:对于串s建后缀自动机,每次询问中,求w对应的子串在s的SAM中的right集合.O(qmk)听上去显然过不了. 数据范围有个∑w<=1e5, ...

随机推荐

  1. ActiveMQ专题2: 持久化

    AMQ的持久化问题 前言 ​ 前面一篇AMQ专题中,我们发现对于Topic这种类型的消息,即使将deliveryMode设置为持久化,只要生产者在消费者之前启动.消息生产者发布的消息还是会丢失.这是符 ...

  2. T4模板根据数据库表和列的Description生成代码的summary的终极解决方案

    相信很多人都用T4模版生成代码,用T4模版生成标准代码真的很方便.我们经常根据表生成相关的代码, 但是估计很多人都遇见过同一个问题, 特别是我们在生成model的时候,代码中model中的Summar ...

  3. el-upload源码跳坑2

    产品又加了一个需求,要求删除图片时候弹一个提示框,如果确定就直接发请求从服务器删除图片 ​ 一开始想的比较简单,直接在on-remove的钩子函数上做弹框提示,如果取消就撤销,代码如下: <el ...

  4. ASCX呼叫ASPX.CS的方法

    为了安全设计,一般情况之下,改用为接口(interface). 在网页中实现这个接口: 用户控件: 当然,把用户控件ascx拉至网页之后,在用户控件的linkbutton的click事件,就可以呼叫至 ...

  5. 解决盒子浮动时margin会显示两倍的美观问题

    当给几个大小一样有boder的盒子浮动时,会出现margin自动加起来的结果. 此时可以给每个盒子一个margin-left:-border的长来实现很好的效果,这样右边的盒子会把左边盒子的右边bor ...

  6. Android Service基础知识你知道多少?

    Android四大组件-Service 多次调用startService会怎样?会执行多次onCreate吗? StopService在哪里调用?stopSelf在哪调用? 怎样使Service被ki ...

  7. nginx命令(持续更新)

    关闭服务:nginx -s stop | service nginx stop 启动服务:nginx | service nginx start 重新加载配置文件:nginx -s reload |  ...

  8. vue 实现点击图片放大

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.建立子组件,来实现图片方法功能: BigImg.vue <template> <!-- 过渡 ...

  9. 【读书笔记】iOS-网络-HTTP-URL结构

    http://user:password@hostname:port/absolute-path?query. http:  协议 user:password@   认证 hostname:  主机名 ...

  10. js获取浏览器和设备相关width(屏幕的宽度)

    首先呢,我们将iPhone手机的相关数据表示如下 我们要理解很多东西,比如逻辑分辨率.物理分辨率.缩放因子.ppi等,这里先不讨论. 首先呢,我们先介绍下各个屏幕宽度: 网页可见区域宽: docume ...