CF547E Mike and Friends 后缀自动机+线段树合并
2024-08-30 07:57:40
裸题,敲完后没调就过了 ~
code:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lson t[x].ls
#define rson t[x].rs
#define setIO(s) freopen(s".in","r",stdin)
const int N=200006;
char str[N];
int tax[N<<1],rk[N<<1];
int n,tot=1,cnt,last,pre[N<<1],ch[N<<1][26],mx[N<<1],rt[N<<1],id[N<<1];
struct node
{
ll sum;
int ls,rs;
}t[N*30];
int newnode()
{
return ++ cnt;
}
void update(int &x,int l,int r,int p,int v)
{
if(!x) x=newnode();
t[x].sum+=v;
if(l==r) return;
int mid=(l+r)>>1;
if(p<=mid) update(lson,l,mid,p,v);
else update(rson,mid+1,r,p,v);
}
int merge(int x,int y)
{
if(!x||!y) return x+y;
int now=newnode();
t[now].sum=t[x].sum+t[y].sum;
t[now].ls=merge(t[x].ls,t[y].ls);
t[now].rs=merge(t[x].rs,t[y].rs);
return now;
}
ll query(int x,int l,int r,int L,int R)
{
if(l>=L&&r<=R) return t[x].sum;
ll re=0;
int mid=(l+r)>>1;
if(L<=mid) re+=query(lson,l,mid,L,R);
if(R>mid) re+=query(rson,mid+1,r,L,R);
return re;
}
void Insert(int c)
{
if(ch[last][c])
{
int p=last,q=ch[last][c];
if(mx[q]==mx[p]+1) last=q;
else
{
int nq=++tot;
last=nq;
mx[nq]=mx[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
pre[nq]=pre[q],pre[q]=nq;
for(;p&&ch[p][c]==q;p=pre[p]) ch[p][c]=nq;
}
}
else
{
int p=last,np=++tot;
mx[np]=mx[p]+1,last=np;
for(;p&&!ch[p][c];p=pre[p]) ch[p][c]=np;
if(!p) pre[np]=1;
else
{
int q=ch[p][c];
if(mx[q]==mx[p]+1) pre[np]=q;
else
{
int nq=++tot;
mx[nq]=mx[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
pre[nq]=pre[q],pre[np]=pre[q]=nq;
for(;p&&ch[p][c]==q;p=pre[p]) ch[p][c]=nq;
}
}
}
}
void M()
{
int i,j;
for(i=2;i<=tot;++i) ++tax[mx[i]];
for(i=1;i<=tot;++i) tax[i]+=tax[i-1];
for(i=1;i<=tot;++i) rk[tax[mx[i]]--]=i;
for(i=tot;i>1;--i)
{
int u=rk[i];
int ff=pre[u];
rt[ff]=merge(rt[ff],rt[u]);
}
}
int main()
{
// setIO("input");
int i,j,m;
scanf("%d%d",&n,&m);
for(i=1;i<=n;++i)
{
scanf("%s",str+1);
int len=strlen(str+1); last=1;
for(j=1;j<=len;++j) Insert(str[j]-'a'),update(rt[last],1,n,i,1);
id[i]=last;
}
M();
for(i=1;i<=m;++i)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%lld\n",query(rt[id[k]],1,n,l,r));
}
return 0;
}
最新文章
- java GZIP压缩和解压
- SPSS二次开发
- GridView自带分页 1总页数 首页 下一页 上一页 尾页 X 页 go 实现方法 .
- ViewPage实现幻灯广告墙
- Dapper中使用存储分页。
- Android中的菜单
- 后缀数组--可重叠的K次最长重复子串(POJ3261)
- TkinterGUI - 初识Tkinter
- API 接口规范
- mysql explain用法和结果的含义
- Odoo 菜单美化的扩展模块
- mobilebone与weiui_example.css 使用问题
- vue-router路由动态传参query和params的区别
- flask-login模块
- 运用Turtle实现汉诺塔的可视化运行(递归算法)
- SSM+MyBatis框架详解
- VMPlayer Ubuntu 16.04 Copy and Paste with Host 主机与宿机之间的复制粘贴
- c#之如何转换文本文件编码格式为utf-8
- dijksta 模板
- Revit 开发将自己的窗口设置为Revit窗口
热门文章
- 阿里云 轻量应用服务器 上传一个HTML文件或者jsp文件 通过外网IP访问
- ubuntu查看软件安装位置
- Python全栈开发相关课程
- Java中守护线程的总结
- .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
- mysql 5.7 非正常安装,无法启动 服务没有报告任何错误
- C# List<;string>;之间的转换
- Tomcat组件梳理—Service组件
- requirejs:模块加载(require)及定义(define)时的路径理解
- vue-cli + webpack 环境搭建