a180285幸运地被选做了地球到喵星球的留学生。他发现喵星人在上课前的点名现象非常有趣。   假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成。喵星球上的老师会选择M个串来点名,每次读出一个串的时候,如果这个串是一个喵星人的姓或名的子串,那么这个喵星人就必须答到。 然而,由于喵星人的字码过于古怪,以至于不能用ASCII码来表示。为了方便描述,a180285决定用数串来表示喵星人的名字。
现在你能帮助a180285统计每次点名的时候有多少喵星人答到,以及M次点名结束后每个喵星人答到多少次吗?  
 
  应该算是后缀数组比较简单的应用了吧...
  首先把所有的串都接起来,中间用不同的分隔符隔开
  然后进行后缀数组将sa,rank,height等数组求出来
  最后枚举每一个点名串,以rank[点名串起点]开始向左和向右拓展
  这里的拓展是指在sa的下标里拓展
  边统计边累计每个喵星人的点到次数
  为了避免一次点名中统计到一个喵星人多次,以及一个喵星人一次点名却统计了多次
  (实际上二者是一样的...)
  都可以用一个标号数组来处理
  然而这个标号数组如果每次fillchar显然不现实...因为太慢...
  然后就运用到KM算法里顶标更新的思想
  当然,再做一次然后把数组还原也是可以的
 
  另外在BZ上PE了一发...行末注意不能留有空格
 program bzoj2754;
const INF = ;maxn = ;
var tota,totb,i,cnt,n,x,j:longint;
a,rank,s,tmp,sa,height,pos,ter,len,vis,ans:array[-..maxn]of longint; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; procedure Suffix_Array;
var sz,i,j,p,v0,v1,v00,v01:longint;
begin
sz:=max(n,INF+);
for i:= to sz do s[i]:=;
for i:= to n- do rank[i]:=a[i];
for i:= to n- do inc(s[rank[i]]);
for i:= to sz do inc(s[i],s[i-]);
for i:=n- downto do
begin
dec(s[rank[i]]);
sa[s[rank[i]]]:=i;
end;
j:=;
while j<=n do
begin
p:=;
for i:=n-j to n- do
begin
tmp[p]:=i;inc(p);
end;
for i:= to n- do if sa[i]-j>= then
begin
tmp[p]:=sa[i]-j;inc(p);
end;
for i:= to sz do s[i]:=;
for i:= to n- do inc(s[rank[i]]);
for i:= to sz do inc(s[i],s[i-]);
for i:=n- downto do
begin
dec(s[rank[tmp[i]]]);
sa[s[rank[tmp[i]]]]:=tmp[i];
end;
p:=;tmp[sa[]]:=;
for i:= to n- do
begin
v0:=sa[i-];v1:=sa[i];
if v0+j<n then v00:=rank[v0+j] else v00:=-;
if v1+j<n then v01:=rank[v1+j] else v01:=-;
if (rank[v0]=rank[v1])and(v00=v01) then tmp[sa[i]]:=p else
begin
inc(p);tmp[sa[i]]:=p;
end;
end;
for i:= to n- do rank[i]:=tmp[i];
j:=j << ;
end;
end; function compare(i,j,x:longint):longint;
begin
while (i+x-<n)and(j+x-<n)and(a[i+x-]=a[j+x-]) do inc(x);
exit(x-);
end; procedure calc_height;
var i:longint;
begin
if rank[]= then height[]:= else height[]:=compare(,sa[rank[]-],);
for i:= to n- do
if rank[i]= then height[i]:= else height[i]:=compare(i,sa[rank[i]-],max(height[i-],));
end; function solve(x,y:longint):longint;
var i,tot:longint;
begin
x:=rank[x];i:=x;tot:=;
while (i>=)and(height[sa[i]]>=y) do
begin
if (pos[sa[i-]]<>)and(vis[pos[sa[i-]]]<>x) then
begin
inc(tot);vis[pos[sa[i-]]]:=x;inc(ans[pos[sa[i-]]]);
end;
dec(i);
end;
i:=x+;
while (i<n)and(height[sa[i]]>=y) do
begin
if (pos[sa[i]]<>)and(vis[pos[sa[i]]]<>x) then
begin
inc(tot);vis[pos[sa[i]]]:=x;inc(ans[pos[sa[i]]]);
end;
inc(i);
end;
exit(tot);
end; begin
readln(tota,totb);cnt:=;n:=-;
for i:= to tota do
begin
read(x);for j:= to x do begin inc(n);read(a[n]);inc(a[n],INF);pos[n]:=i;end;
inc(cnt);inc(n);a[n]:=cnt;
read(x);for j:= to x do begin inc(n);read(a[n]);inc(a[n],INF);pos[n]:=i;end;
inc(cnt);inc(n);a[n]:=cnt;
end;
for i:= to totb do
begin
ter[i]:=n+;
read(x);for j:= to x do begin inc(n);read(a[n]);inc(a[n],INF);end;
len[i]:=x;
inc(cnt);inc(n);a[n]:=cnt;
end;
fillchar(vis,sizeof(vis),);
inc(n);
suffix_array; calc_height;
fillchar(ans,sizeof(ans),);
for i:= to totb do writeln(solve(ter[i],len[i]));
for i:= to tota- do write(ans[i],' ');writeln(ans[tota]);
end.
 
 

[BZOJ2754] [SCOI2012]喵星球上的点名解题报告|后缀数组的更多相关文章

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

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

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

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

  3. BZOJ2754: [SCOI2012]喵星球上的点名

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 680  Solved: 314[Submit][Sta ...

  4. BZOJ_2754__[SCOI2012]_喵星球上的点名_(暴力+后缀数组)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=2754 给出n个姓名串和m个点名串.求每个点名串在多少人的姓名中出现过(在名中出现或在姓中出现, ...

  5. bzoj2754:[SCOI2012]喵星球上的点名(后缀自动机)

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

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

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

  7. BZOJ2754 SCOI2012喵星球上的点名

    绝世好题. 正当我犹豫不决时,hzwer说:“MAP!!!” 没错这题大大的暴力,生猛的stl,贼基尔爽,,ԾㅂԾ,, 由于我们求点名在名字中的子串个数,所以将点名建AC自动机,记录节点属于哪次点名, ...

  8. BZOJ2754 [SCOI2012]喵星球上的点名 SA+莫队+树状数组

    题面 戳这里 题解 首先先把所有给出的姓名和询问全部接在一起,建出\(height\)数组. 某个串要包含整个询问串,其实就相当于某个串与询问串的\(lcp\)为询问串的长度. 而两个后缀\(Suff ...

  9. [SCOI2012]喵星球上的点名(树状数组+后缀数组)

    我们把所有的名,姓,询问都拼起来构成一个新的长串,然后跑一边SA.排完序后对于每一个询问,我们可以二分求出它所对应的区间(即满足这个区间的前缀都是这个询问串).然后问题就转化为很多区间问区间出现过的不 ...

随机推荐

  1. 计算器软件实现系列(七)WPF+SQL+策略模式

    一  整体概述 本次设计主要是在WPF的页面中实现的,属于表现层的更换,数据库部分用的还是数据库的封装,其中引用了策略模式 二  设计思路 1 在出题页面,进行试题的编辑,在编辑后会自动保存到数据库中 ...

  2. 如何用vs查看框架函数管道模型

    调试状态下 函数调用的 代码图,我们可以看到MVC框架的函数管道模型 源文章标题: 源文章:https://www.cnblogs.com/1996V/p/9037603.html 扩展阅读:http ...

  3. ARKit----学习一

    一.ARKit的简介 开始进入正题吧 ARKit在iOS 11上推出的一个AR移动平台,支持A9以上的处理器,不支持模拟器.ARKit使用相机捕捉现实世界,使用SceneKit,SpriteKit或者 ...

  4. 数据存储到MySQL并返回新插入的id值

    当对数据库进行插入数据后,有时会需要刚插入的数据的id值,以作他用,整理如下: conn = pymysql.connect(, user=DB_USER, passwd=DB_PASSWORD, d ...

  5. js alert()后进行跳转的方法

    如果alert()之后再进行跳转本页,按以下方法你将等不到alert(),浏览器就本身刷新本页面了 <script type="text/javascript"> al ...

  6. 【.Net】浅谈C#中的值类型和引用类型

    在C#中,值类型和引用类型是相当重要的两个概念,必须在设计类型的时候就决定类型实例的行为.如果在编写代码时不能理解引用类型和值类型的区别,那么将会给代码带来不必要的异常.很多人就是因为没有弄清楚这两个 ...

  7. Gevent-自动挡切换

    Gevent: Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程. G ...

  8. 注解失效,@SpringBootApplication 失效,引入包失效

    因为同时修改两个springboot工程,其中把一个工程的版本调整到2.0.2.RELEASE,然后坑爹的事情出现了,所有springboot工程的@SpringBootApplication失效, ...

  9. POJ2826:An Easy Problem?!——题解(配特殊情况图)

    http://poj.org/problem?id=2826 题目大意:给两条线,让它接竖直下的雨,问其能装多少横截面积的雨. ———————————————————————————— 水题,看题目即 ...

  10. 洛谷 P2906 [USACO08OPEN]牛的街区Cow Neighborhoods | Set+并查集

    题目: https://www.luogu.org/problemnew/show/P2906 题解: 垃圾水题 #include<cstdio> #include<algorith ...