P2336 [SCOI2012]喵星球上的点名

名字怎么存?显然是后缀自动机辣

询问点到多少个喵喵喵其实就是

查询后缀自动机上parent树的一个子树

于是我们考虑莫队

怎么树上莫队呢

我们用dfs序处理后缀自动机上的parent树

把parent树映射到序列上

于是我们就可以愉快地莫队辣

最后怎么处理每个喵喵喵被点到的次数呢

我们在莫队的时候维护一个$Ls[i]$数组维护颜色$i$的存在时间(显然会被划分为好几段)

当颜色$i$第一次进队(队内本来没有该颜色)时,就记下$Ls[i]$

当队中最后一个颜色$i$出队时,答案就累加上$now-Ls[i]$,即为颜色$i$在这段的存在时间

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#define rint register int
using namespace std;
int read(){
char c=getchar();int x=;
while(c<''||c>'') c=getchar();
while(''<=c&&c<='') x=x*+(c^),c=getchar();
return x;
}
#define N 200005
int n,m,Len,L,R,dfn[N],siz[N],Co[N];
int tt,in[N],Ls[N],ans1[N],ans2[N],tot;
int cnt,hd[N],nxt[N],ed[N],poi[N];
struct data{int l,r,Id;}a[N];
inline bool cmp(data A,data B){
return (A.l/Len==B.l/Len)?A.r<B.r:A.l/Len<B.l/Len;
}
inline void adde(int x,int y){
nxt[ed[x]]=++cnt, hd[x]=hd[x]?hd[x]:cnt,
ed[x]=cnt, poi[cnt]=y;
}
struct Sam{
int fa[N],len[N],col[N],ed,q,Clock;
Sam(){Clock=;ed=;}
map<int,int> mp[N];
int add(int p,int x,int id){
len[++ed]=len[p]+; col[ed]=id;
for(;p&&!mp[p][x];p=fa[p]) mp[p][x]=ed;
if(!p) {fa[ed]=;return ed;}
q=mp[p][x];
if(len[q]==len[p]+){fa[ed]=q;return ed;}
len[++ed]=len[p]+; mp[ed]=mp[q];
fa[ed]=fa[q]; fa[q]=fa[ed-]=ed;
for(;mp[p][x]==q;p=fa[p]) mp[p][x]=ed;
return ed-;
}
void link(){for(rint i=;i<=ed;++i) adde(fa[i],i);}
void dfs(int x){//dfs序把parent树映射到序列上
dfn[x]=++Clock; Co[Clock]=col[x]; siz[x]=;
for(int i=hd[x];i;i=nxt[i])
dfs(poi[i]),siz[x]+=siz[poi[i]];
}
}S;
int main(){
n=read();m=read();int q,now;
for(rint i=;i<=n;++i){
q=read(); now=;
while(q--) now=S.add(now,read(),i);
q=read(); now=;
while(q--) now=S.add(now,read(),i);
}S.link(); S.dfs(); Len=sqrt(S.ed);
for(rint i=;i<=m;++i){
q=read();now=;
while(q--) now=S.mp[now][read()];
if(!now) continue;
a[++tt]=(data){dfn[now],dfn[now]+siz[now]-,i};
}
if(tt){//在映射序列上进行莫队
sort(a+,a+tt+,cmp);
for(rint i=a[].l;i<=a[].r;++i){
if(!in[Co[i]]&&Co[i]) ++tot,Ls[Co[i]]=;
++in[Co[i]];
}ans1[a[].Id]=tot; L=a[].l; R=a[].r;
for(rint i=;i<=tt;++i){
while(L<a[i].l){
--in[Co[L]];
if(!in[Co[L]]&&Co[L]) --tot,ans2[Co[L]]+=i-Ls[Co[L]];
++L;
}
while(R>a[i].r){
--in[Co[R]];
if(!in[Co[R]]&&Co[R]) --tot,ans2[Co[R]]+=i-Ls[Co[R]];
--R;
}
while(L>a[i].l){
--L;
if(!in[Co[L]]&&Co[L]) ++tot,Ls[Co[L]]=i;
++in[Co[L]];
}
while(R<a[i].r){
++R;
if(!in[Co[R]]&&Co[R]) ++tot,Ls[Co[R]]=i;
++in[Co[R]];
}
ans1[a[i].Id]=tot;
}
while(L<=R){
--in[Co[L]];
if(!in[Co[L]]&&Co[L]) --tot,ans2[Co[L]]+=tt-Ls[Co[L]]+;
++L;
}//注意最后剩下的数据要算进去
}
for(rint i=;i<=m;++i) printf("%d\n",ans1[i]);
for(rint i=;i<=n;++i) printf("%d ",ans2[i]);
return ;
}

P2336 [SCOI2012]喵星球上的点名(后缀自动机+莫队+dfs序)的更多相关文章

  1. P2336 [SCOI2012]喵星球上的点名(SA+莫队)

    题面传送门 一道还算有点含金量的 SA 罢-- 首先按照套路我们把读入的所有字符串都粘在一起,中间用分隔符隔开并建出后缀数组出来. 我们考虑对于一个固定的字符串 \(s\),什么样的字符串 \(t\) ...

  2. Luogu2336 SCOI2012 喵星球上的点名 SA、莫队

    传送门 一道很套路的题目 先将所有串拼在一起,两个不同的串之间放一个没有出现在任何串中的字符做分隔,然后SA 那么对于所有点名串能够点到的名字串在SA中对应一段区间 把这些区间拿出来然后莫队统计每一个 ...

  3. 洛咕 P2336 [SCOI2012]喵星球上的点名

    洛咕 P2336 [SCOI2012]喵星球上的点名 先求出SA和height,一个点名串对应的就是一段区间,还有很多个点,就转化成了 有很多个区间,很多个点集,对每个区间计算和多少个点集有交,对每个 ...

  4. 洛谷 P2336 [SCOI2012]喵星球上的点名 解题报告

    P2336 [SCOI2012]喵星球上的点名 题目描述 a180285 幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有 \(N\) 个喵星人,每个喵星人的 ...

  5. BZOJ 2754: [SCOI2012]喵星球上的点名 [后缀数组+暴力]

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1906  Solved: 839[Submit][St ...

  6. BZOJ 2754: [SCOI2012]喵星球上的点名 [AC自动机+map+暴力]

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1902  Solved: 837[Submit][St ...

  7. BZOJ2754: [SCOI2012]喵星球上的点名(AC自动机/后缀自动机)

    Description a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣.   假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串 ...

  8. BZOJ2754: [SCOI2012]喵星球上的点名(AC自动机)

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2816  Solved: 1246[Submit][Status][Discuss] Descript ...

  9. 洛谷P2336 [SCOI2012]喵星球上的点名(后缀数组+莫队)

    我学AC自动机的时候就看到了这题,想用AC自动机结果被学长码风劝退-- 学后缀数组时又看到了这题--那就写写后缀数组做法吧 结果码风貌似比当年劝退我的学长还毒瘤啊 对所有的模式串+询问串,不同串之间用 ...

随机推荐

  1. word2vec 评测 sg=0 sg=1 size=100 window=3

    1.评价sg=0与sg=1的区别    结果原文:sg_difference.txt sg=0     sg=1 绑定                         1 关联            ...

  2. Centos ssh 限制ip访问

    要确定客户端计算机是否允许连接到服务,TCP包装器将引用以下两个文件,这两个文件通常称为主机访问文件: /etc/hosts.allow /etc/hosts.deny 当TCP包裹服务接收到客户端请 ...

  3. DropzoneJS是一个提供文件拖拽上传并且提供图片预览的开源类库.

    DropzoneJS是一个提供文件拖拽上传并且提供图片预览的开源类库. 它是轻量级的,不依赖任何其他类库(如JQuery)并且高度可定制. 试试看! 将文件拖至此处或点击上传.(这仅仅是 dropzo ...

  4. 响应式布局css样式

    核心css /*图片列表样式*/ .img-list{ margin:-15px 0 0 -15px; *display:inline-block; } /*响应式布局*/ @media screen ...

  5. LeetCode107.二叉树的层次遍历II

    给定一个二叉树,返回其节点值自底向上的层次遍历. (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 例如:给定二叉树 [3,9,20,null,null,15,7], 3 / \ 9 20 ...

  6. jQuery-设计模式

    [目录] 一.选择网页元素 二.改变结果集 三.链式操作 四.元素的操作:取值和赋值 五.元素的操作:移动 六.元素的操作:复制.删除和创建 七.工具方法 八.事件操作 九.特殊效果 [正文] 一.选 ...

  7. C# 如何批量修改集合元素的属性值?

    我们往往会遇到要批量修改集合中元素的值,最笨的办法就是foreach循环,但本文介绍几种优雅的方法. 首先,我们准备好元素类和初始集合: 下面就是几种方法,目前并没有对性能做进一步的测试,有兴趣的童鞋 ...

  8. Mongodb内嵌数组的完全匹配查询

    样例数据: {      "cNo" : "11",     "Details" : [         {              &q ...

  9. 参考termux中包管理命令的伪装修改的arch版包管理命令

    #!/bin/bash set -e -u show_help() { echo "This help message is useless, please read the content ...

  10. gedit emacs

    emacs常用操作: 1)C-g:退出当前命令 2)C-x C-f:搜索文件打开 3)C-s:向前搜索 C-r:向后搜索 4)C-x 2:水平分割窗口 C-x 3:竖直分割窗口 5)C-x o:切换窗 ...