P2336 [SCOI2012]喵星球上的点名(后缀自动机+莫队+dfs序)
名字怎么存?显然是后缀自动机辣
询问点到多少个喵喵喵其实就是
查询后缀自动机上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序)的更多相关文章
- P2336 [SCOI2012]喵星球上的点名(SA+莫队)
题面传送门 一道还算有点含金量的 SA 罢-- 首先按照套路我们把读入的所有字符串都粘在一起,中间用分隔符隔开并建出后缀数组出来. 我们考虑对于一个固定的字符串 \(s\),什么样的字符串 \(t\) ...
- Luogu2336 SCOI2012 喵星球上的点名 SA、莫队
传送门 一道很套路的题目 先将所有串拼在一起,两个不同的串之间放一个没有出现在任何串中的字符做分隔,然后SA 那么对于所有点名串能够点到的名字串在SA中对应一段区间 把这些区间拿出来然后莫队统计每一个 ...
- 洛咕 P2336 [SCOI2012]喵星球上的点名
洛咕 P2336 [SCOI2012]喵星球上的点名 先求出SA和height,一个点名串对应的就是一段区间,还有很多个点,就转化成了 有很多个区间,很多个点集,对每个区间计算和多少个点集有交,对每个 ...
- 洛谷 P2336 [SCOI2012]喵星球上的点名 解题报告
P2336 [SCOI2012]喵星球上的点名 题目描述 a180285 幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有 \(N\) 个喵星人,每个喵星人的 ...
- BZOJ 2754: [SCOI2012]喵星球上的点名 [后缀数组+暴力]
2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1906 Solved: 839[Submit][St ...
- BZOJ 2754: [SCOI2012]喵星球上的点名 [AC自动机+map+暴力]
2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1902 Solved: 837[Submit][St ...
- BZOJ2754: [SCOI2012]喵星球上的点名(AC自动机/后缀自动机)
Description a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串 ...
- BZOJ2754: [SCOI2012]喵星球上的点名(AC自动机)
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2816 Solved: 1246[Submit][Status][Discuss] Descript ...
- 洛谷P2336 [SCOI2012]喵星球上的点名(后缀数组+莫队)
我学AC自动机的时候就看到了这题,想用AC自动机结果被学长码风劝退-- 学后缀数组时又看到了这题--那就写写后缀数组做法吧 结果码风貌似比当年劝退我的学长还毒瘤啊 对所有的模式串+询问串,不同串之间用 ...
随机推荐
- python接口测试-充值
import requests import json import unittest import HTMLTestRunner telphone =18200717087 #参数化手机号码 ur1 ...
- [LeetCode] 130. Surrounded Regions_Medium tag: DFS/BFS
Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. A reg ...
- IntelliJ IDEA 17 本地LicenseServer激活
注意:此方法适用于Idea v2017.2.x 版本及以前版本. IntelliJ IDEA及破解包下载地址:百度网盘 密码:hlko 一.将IntelliJIDEALicenseServer.e ...
- JAVA编程思想学习笔记5-chap13-15-斗之气5段
1.String对象不可变,一旦发生字符变换或者变长度,一定是新建了一个String private final char value[]; 2.字符串+与+=:唯二操作符重载 "aaa&q ...
- (已解决)cocos2d-x 运行时xcode提示错误:"vtable for XXX", referenced from;
vtable/引用和虚函数相关,今天在添加一个层的时候报了这个错误,很低级的错误,忘了实现虚函数了(谨记!!) 若如果实现了虚函数还依然如此的话,可能是创建的时候忘了钩上 -desktop 选项了,把 ...
- Mac虚拟机上使用Genumotion模拟器
在Mac虚拟机系统上开发ReactNative的IOS应用非常方便,只要安装Xcode即可, 但 Android应用就需要三个步骤: 首先声明,下载Android SDK会非常慢,最好有快速的网络或 ...
- 软件常用设置(VC, eclipse ,nodejs)---自己备用
留存复制使用 1.VC ----1.1VC项目设置 输出目录: $(SolutionDir)../bin/$(platform)/$(Configuration) $(ProjectDir)../bi ...
- Eclipse修改编码方式
1.修改工作空间默认编码 1.修改工作空间默认编码:window -> preferences -> General -> Workspace 2.修改文件的编码 在Eclipse ...
- STL之List容器
1.List容器 1) list是一个双向链表容器,可高效地进行插入删除元素. 2)list不可以随机存取元素,所以不支持at.(pos)函数与[]操作符.It++(ok) it+5(err) 3)头 ...
- Cipher
Description Bob and Alice started to use a brand-new encoding scheme. Surprisingly it is not a Publi ...