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自动机结果被学长码风劝退-- 学后缀数组时又看到了这题--那就写写后缀数组做法吧 结果码风貌似比当年劝退我的学长还毒瘤啊 对所有的模式串+询问串,不同串之间用 ...
随机推荐
- 【LeetCode每天一题】Add Two Numbers(两链表相加)
You are given two non-empty linked lists representing two non-negative integers. The digits are stor ...
- mac本的环境基本完成大部分了
1.禅道的部署,技术上最难搞 session 目录存储目录不存在的处理 终端:open /et 前往——>前往文件夹——〉/资源库/WebServer/Documents/ 在tem目录下新建文 ...
- [LeetCode] 762. Prime Number of Set Bits in Binary Representation_Easy
Given two integers L and R, find the count of numbers in the range [L, R] (inclusive) having a prime ...
- statement对象与sql语句(新手)
本篇介绍读上篇代码中的疑惑点 实现简单网页上对数据内容进行增删改查,需要用到三个部分:jsp网页前端部分+java后台程序+数据库表 一.创建一个Statement (用于在已经建立数据库连接的基础上 ...
- js分页器插件
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- python regularexpress
这个正则表达式,我还真没有接触过,在python首次学习 //test.py 1 import re 2 3 print (re.match('www', 'www.myweb.com').span( ...
- Amber TUTORIAL B5: Simulating the Green Fluorescent Protein
Section 1: Preparing the PDB file 1EMA是本次教程所用的pdb,可以在PDB数据库下载. pdb4amber -i 1EMA.pdb -o gfp.pdb --dr ...
- vue中使用导出表格功能
1.下载依赖 npm install -S file-saver xlsx npm install -D script-loader 2.在src下创建vendor文件夹,并在文件夹中放两个文件 Bl ...
- Nginx.代理MySQL
Nginx.代理MySQL 1. Nginx在安装的时候,需要加上一个参数:--with-stream 即Nginx安装指令为:./configure --prefix=/u01/app/nginx ...
- c#之枚举,结构体
1.枚举 2.结构体 例子1: using System; using System.Collections.Generic; using System.Linq; using System.Text ...