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. OSG学习:矩阵变换节点示例

    #include<osgViewer\Viewer> #include<osg\Node> #include<osg\Geode> #include<osg\ ...

  2. 【OSG】 报错:丢失osg100-osgDB.dll

    如果你bin目录已经添加到了环境变量的path里面,还报这个错的话. 或许你重启一下电脑就可以了..我就这么解决的.

  3. RabbitMQ安装与初始配置【转载】

    Erlang安装 rabbitmq依赖于Erlang,需先安装,推荐安装rabbitmq/erlang-rpm: #clone源码 git clone https://github.com/rabbi ...

  4. 【Redis】- 延时任务

    引言 在开发中,往往会遇到一些关于延时任务的需求.例如 生成订单30分钟未支付,则自动取消 生成订单60秒后,给用户发短信 对上述的任务,我们给一个专业的名字来形容,那就是延时任务.那么这里就会产生一 ...

  5. IIS发布 MVC 配置

    E:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll

  6. PL/SQL在 win8.1系统下连接Oracle11g没有database处理方法(亲身实验,吐血分享)

    一.问题 这里首先说明下我的环境:win8.1(64bit)+oracle11g(64bit)+PL/SQL(32bit).状况是:net manager正常配置,测试也成功,但是用PL/SQL连接的 ...

  7. Qt——设计颜色编辑选取对话框

    Qt中已经有一些封装好的对话框,比如QMessageBox.QColorDialog等,使用起来快捷方便,但缺点是我们无法为它们自定义样式,所以可能难以“融入”我们的项目.既然如此,那就自己做一个把. ...

  8. HTML表单之input元素的23种type类型

    摘自:http://www.cnblogs.com/xiaohuochai/p/5179909.html 了解HTML表单之input元素的23种type类型 随着HTML5的出现,input元素新增 ...

  9. POJ2187:Beauty Contest——题解

    http://poj.org/problem?id=2187 题目大意:给n个点,求点对最大距离的平方. ———————————————————— 很容易证明最大距离的点对在最大凸包上. 那么就是旋转 ...

  10. Wireshark中TCP segment of a reassembled PDU的含义

    By francis_hao    Sep 16,2017   在用Wireshark抓包的时候,经常会看到TCP segment of a reassembled PDU,字面意思是要重组的协议数据 ...