upd:感谢评论里@spacevortex 指正 暴力链加复杂度是$O(\sum |s|)$的 也可以通过owo

子串看起来就很SuffixStructures

于是上SAM

本来想着直接LCT

后来发现没法串定位(暴力匹配复杂度不对)

然后就离线吧,先建出来然后链加子树和,树剖就odk。

其实更直接的套路是线段树合并right集合维护。

这个题很像BZOJ3881 那个题更复杂一点,需要树链的并(到时候看看这个题可不可以加强一下扔到校内模拟赛

当然还有正确的ACA写法,直接FAIL树上主席树。(就更像BZOJ3881了

(但感觉都很暴力,我的想法貌似还挺好的)

顺便学习了广义SAM的正确写法。(发现之前的写法死活改不对

//Love and Freedom.
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define ll long long
#define inf 20021225
#define N 200010
#define pb push_back
using namespace std;
int read()
{
int s=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-') f=-; ch=getchar();}
while(ch>=''&&ch<='') s=s*+ch-'',ch=getchar();
return f*s;
}
struct node{int ch[],fa,len;}t[N<<];
struct edge{int to,lt;}e[N<<];
int lt,poi,cnt,rt,ed[N],in[N<<];
vector<int> endpos;
void insert(int c,int id)
{
if(t[lt].ch[c])
{
int p=lt,np=lt=t[p].ch[c];
if(t[np].len==t[p].len+) ed[id]=np,endpos.pb(np);
else
{
int nq=++poi; ed[id]=nq; endpos.pb(nq); t[nq].len=t[p].len+;
memcpy(t[nq].ch,t[np].ch,sizeof(t[np].ch));
t[nq].fa=t[np].fa; t[np].fa=nq;
for(;p&&t[p].ch[c]==np;p=t[p].fa) t[p].ch[c]=nq;
lt=nq;
}
return;
}
int p=lt,np=lt=++poi; endpos.pb(np); ed[id]=np; t[np].len=t[p].len+;
for(;p&&!t[p].ch[c];p=t[p].fa) t[p].ch[c]=np;
if(!p){t[np].fa=rt; return;} int q=t[p].ch[c];
if(t[q].len==t[p].len+){t[np].fa=q; return;}
int nq=++poi; t[nq].fa=t[q].fa; t[q].fa=t[np].fa=nq;
memcpy(t[nq].ch,t[q].ch,sizeof(t[q].ch)); t[nq].len=t[p].len+;
for(;p&&t[p].ch[c]==q;p=t[p].fa) t[p].ch[c]=nq;
}
#define lowbit(x) (x&-x)
int tr[N<<];
void add(int x,int v){while(x<=poi) tr[x]+=v,x+=lowbit(x);}
void modify(int l,int r,int v){add(l,v); add(r+,-v);}
int query(int x){int a=; while(x) a+=tr[x],x-=lowbit(x); return a;}
int dfn[N<<],tot,sz[N<<],son[N<<],idfn[N<<],top[N<<],fa[N<<];
void addedge(int x,int y){e[++cnt].to=y; e[cnt].lt=in[x]; in[x]=cnt;}
void build(){for(int i=;i<=poi;i++) addedge(t[i].fa,i);}
void dfs(int x,int fr)
{
fa[x]=fr; sz[x]=;
for(int i=in[x];i;i=e[i].lt)
{
int y=e[i].to; dfs(y,x);
sz[x]+=sz[y]; if(sz[y]>=sz[son[x]]) son[x]=y;
}
}
void dfs2(int x,int t)
{
top[x]=t; dfn[x]=++tot; idfn[tot]=x; if(!son[x]) return; dfs2(son[x],t);
for(int i=in[x];i;i=e[i].lt) if(e[i].to!=son[x]) dfs2(e[i].to,e[i].to);
}
void modify(int x,int v)
{
while(x) modify(dfn[top[x]],dfn[x],v), x=fa[top[x]];
}
int ask(int x){return query(dfn[x]);}
#define Q 500010
int n,q; char ch[N]; int ans[Q],pre[N];
struct qry{int id,opt,pos,x;}r[Q<<]; int qwq;
bool operator<(qry a,qry b){return a.pos<b.pos;}
int main()
{
n=read(),q=read(); poi=rt=lt=; int tot=;
for(int i=;i<=n;i++)
{
scanf("%s",ch+); lt=rt; int sn=strlen(ch+);
for(int j=;j<=sn;j++) ++tot,insert(ch[j]-'a',i);
pre[i]=tot;
}
int L,R,K; build(); dfs(,); dfs2(,);
for(int i=;i<=q;i++)
L=read(),R=read(),K=read(),
r[++qwq].id=i,r[qwq].opt=-,r[qwq].pos=pre[L-],r[qwq].x=ed[K],
r[++qwq].id=i,r[qwq].opt=,r[qwq].pos=pre[R],r[qwq].x=ed[K];
int p=; sort(r+,r+qwq+);
while(p<=qwq&&!r[p].pos) p++;
for(int i=;i<endpos.size();i++)
{
int pos=endpos[i]; modify(pos,);
while(p<=qwq&&r[p].pos==i+) ans[r[p].id]+=r[p].opt*ask(r[p].x),p++;
}
for(int i=;i<=q;i++) printf("%d\n",ans[i]);
return ;
}

CF547E Mike and Friends的更多相关文章

  1. CF547E Mike and Friends 后缀自动机+线段树合并

    裸题,敲完后没调就过了 ~ code: #include <bits/stdc++.h> using namespace std; #define ll long long #define ...

  2. CF547E Mike and Friends [AC自动机,离线树状数组]

    #include <cstdio> #include <queue> #include <vector> #define pb emplace_back using ...

  3. cf#305 Mike and Foam(容斥)

    C. Mike and Foam time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  4. CF #305(Div.2) D. Mike and Feet(数学推导)

    D. Mike and Feet time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  5. CF #305 (Div. 2) C. Mike and Frog(扩展欧几里得&&当然暴力is also no problem)

    C. Mike and Frog time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  6. codeforces 361 E - Mike and Geometry Problem

    原题: Description Mike wants to prepare for IMO but he doesn't know geometry, so his teacher gave him ...

  7. codeforces 361 A - Mike and Cellphone

    原题: Description While swimming at the beach, Mike has accidentally dropped his cellphone into the wa ...

  8. codeforces 361 B - Mike and Shortcuts

    原题: Description Recently, Mike was very busy with studying for exams and contests. Now he is going t ...

  9. CodeForces 689C Mike and Chocolate Thieves (二分)

    原题: Description Bad news came to Mike's village, some thieves stole a bunch of chocolates from the l ...

随机推荐

  1. 一、Jmeter启动报错:Could not initialize class org.apache.jmeter.gui.util.MenuFactory

    1.下载: plugins-manager.jar 包 2.地址:https://jmeter-plugins.org/install/Install/ 3.将jar包放到lib/ext 4.重启jm ...

  2. 八、RF的内置变量

    1.表示“空”的变量 ${EMPTY} 空 适用输入空的案例 2.表示“空格”的变量 ${SPACE} 空格,如果是需要5个空格可以这样写${SPACE*5} 3.目录的绝对路径 ${CURDIR} ...

  3. nginx创建默认虚拟主机

    创建默认虚拟主机配置文件作用:禁止任何人通过ip或未允许的域名访问web服务. 如:vim vhosts/default.conf server { listen 80 default; server ...

  4. python string_3 end 内建函数详解

    以下方法,是在python2上运行的,编码也使用的是python2, 在对比python3后,发现,基本相同,也就是说在print后补上(),使用函数方式,是可以在python3下运行的, 删除了针对 ...

  5. pyinstaller如何将自己写的模块一并打包到exe中

    使用pyinstaller命令 pyinstaller -F main.py 打包时,若mian.py代码中存在引入自己写的模块,而打包成exe文件时,并不会自动引入自己写的模块,打包成功后,点击打开 ...

  6. angular5 给元素添加自定义属性

    今天尝试给一个a 标签添加一个自定义属性,用于存放相关数据,但是angular templates 编译不通过. <a href="javascript:void(0);" ...

  7. & 和 && 区别和联系,| 和 || 区别和联系

    & 和 && 区别和联系,| 和 || 区别和联系,实际项目中,什么情况用哪种? 首先,& 和 && 的联系(共同点): & 和 &&a ...

  8. 【监控笔记】【1.4】Pssdiag和Sqldiag管理器

    --没有实操过,有点复杂,先写上以后有用到再深入研究 统计与诊断数据是任何 SQL故障修复工作的关键所在. 如果没有掌握这些数据,就无法确定数据性能问题的根源.数据表的瓶颈可能并不是由索引问题造成的: ...

  9. 极*Java速成教程 - (7)

    Java高级特性 数组 在Java中,数组是一串连续的,不可改变长度的,对象被固定的,类型固定的连续空间.数组中的随机访问非常迅速,但为了速度放弃了灵活性.而效率也是数组最大的优点. 在使用泛型的容器 ...

  10. 《剑指offer》面试题24 二叉搜索树的后序遍历序列 Java版

    (判断一个元素均不相同的序列是否为一个BST的LRD) 书中方法:首先对于二叉搜索树,左子树中的所有元素小于根节点小于右子树中的所有元素,然后后序遍历序列最后一个元素是根节点,这是我们已知的条件.这道 ...