看到这道题一开始想到的是后缀数组+二分+rmq

类似bzoj3172

问每个串i在合并后的串出现了多少次

等价于有多少个后缀j,使得LCP(i,j)>=length(s[i])

但是想想又不对,要求求的是有多少人被点到,每个人点到多少次

可能有多个后缀j满足条件但其实都是一个人的名字的一部分

好像二分搞不动,只能顺着名次依次找,理论上极其极端的数据是可以卡掉

但是实际却过了,,内疚啊……

UPD:太神了,这题有非暴力的做法,orz http://oi.nks.edu.cn/showmessage?message_id=4091

 const inf=;
var s,sum,be,h,x,y,rank,sa:array[..] of longint;
    q,len,w:array[..] of longint;
    v:array[..] of boolean;
    tot,c,p,m,n,t,l,i,j:longint; function min(a,b:longint):longint;
  begin
    if a>b then exit(b) else exit(a);
  end; procedure suffix(n:longint);
  var m:longint;
  begin
    for i:= to t do
      inc(sum[s[i]]);
    m:=inf;
    for i:= to m do
      inc(sum[i],sum[i-]);
    for i:=n downto   do
    begin
      sa[sum[s[i]]]:=i;
      dec(sum[s[i]]);
    end;
    p:=;
    rank[sa[]]:=;
    for i:= to n do
    begin
      if (s[sa[i]]<>s[sa[i-]]) then inc(p);
      rank[sa[i]]:=p;
    end;
    m:=p;
    j:=;
    while m<n do
    begin
      fillchar(sum,sizeof(sum),);
      y:=rank;
      p:=;
      for i:=n-j+ to n do
      begin
        inc(p);
        x[p]:=i;
      end;
      for i:= to n do
        if sa[i]>j then
        begin
          inc(p);
          x[p]:=sa[i]-j;
        end;       for i:= to n do
      begin
        rank[i]:=y[x[i]];
        inc(sum[rank[i]]);
      end;
      for i:= to m do
        inc(sum[i],sum[i-]);
      for i:=n downto do
      begin
        sa[sum[rank[i]]]:=x[i];
        dec(sum[rank[i]]);
      end;
      p:=;
      rank[sa[]]:=;
      for i:= to n do
      begin
        if (y[sa[i]]<>y[sa[i-]]) or (y[sa[i]+j]<>y[sa[i-]+j]) then inc(p);
        rank[sa[i]]:=p;
      end;
      m:=p;
      j:=j shl ;
    end;
    h[]:=;
    p:=;
    for i:= to n do
    begin
      if rank[i]= then continue;
      j:=sa[rank[i]-];
      while s[i+p]=s[j+p] do inc(p);
      h[rank[i]]:=p;
      if p> then dec(p);
    end;
  end; begin
  readln(n,m);
  for i:= to n do
  begin
    read(l);
    for j:= to l do
    begin
      inc(t);
      read(s[t]);
      be[t]:=i;
    end;
    inc(t);
    s[t]:=inf;  //注意姓和名之间也要加分隔符,防止点名串一部分在姓,一部分在名的情况
    read(l);
    for j:= to l do
    begin
      inc(t);
      read(s[t]);
      be[t]:=i;
    end;
    inc(t);
    s[t]:=inf;
  end;
  for i:= to m do
  begin
    read(len[i]);
    w[i]:=t+;
    for j:= to len[i] do
    begin
      inc(t);
      read(s[t]);
      be[t]:=i+n;
    end;
    inc(t);
    s[t]:=inf;
  end;
  suffix(t);
  fillchar(sum,sizeof(sum),);
  tot:=;
  for i:= to m do
  begin
    for j:= to tot do  //小小优化
      v[q[j]]:=false;
    tot:=;
    j:=rank[w[i]];
    l:=;
    while j<=t do      //找名次比点名串大的后缀
    begin
      inc(j);
      c:=sa[j];
      l:=min(h[j],l);    //height数组和LCP的关系
      if l<len[i] then break
      else begin
        if (be[c]>=) and (be[c]<=n) and not v[be[c]] then
        begin
          v[be[c]]:=true;  //不能重复统计
          inc(tot);
          q[tot]:=be[c];
          inc(sum[be[c]]);
        end;
      end;
    end;
    j:=rank[w[i]];
    l:=h[j];
    while j> do     //找名次比点名串小的后缀
    begin
      dec(j);
      c:=sa[j];
      if l<len[i] then break
      else begin
        if (be[c]>=) and (be[c]<=n) and not v[be[c]] then
        begin
          v[be[c]]:=true;
          inc(tot);
          q[tot]:=be[c];
          inc(sum[be[c]]);
        end;
      end;
      l:=min(l,h[j]);
    end;
    writeln(tot);
  end;
  for i:= to n do
  begin
    write(sum[i]);
    if i<>n then write(' ');
  end;
  writeln;
end.

bzoj2754的更多相关文章

  1. 【BZOJ2754】喵星球上的点名(AC自动机)

    [BZOJ2754]喵星球上的点名(AC自动机) 题面 BZOJ 题解 友情提示:此题请不要在cogs上提交,它的数据有毒 对于点名串构建\(AC\)自动机 然后把名字丢进去进行匹配, 大力统计一下答 ...

  2. 【bzoj2754】 SCOI2012—喵星球上的点名

    http://www.lydsy.com/JudgeOnline/problem.php?id=2754 (题目链接) 题意 给出$n$个名字串,$m$个点名串,问对于每一个姓名串,它包含多少个点名串 ...

  3. 【bzoj2754】【scoi2012】喵星球上的点名

    题解们: 1.首先可以被很多暴力给搞过去:我以前也是这样水过去的 2.ac自动机 2.1 抽离fail树 对点名建自动机,建$fail$树的时候只保留询问节点: 对于一个喵,子串==在自动机里匹配到的 ...

  4. 【BZOJ2754】[SCOI2012]喵星球上的点名

    [BZOJ2754][SCOI2012]喵星球上的点名 题面 bzoj 洛谷 题解 这题有各种神仙做法啊,什么暴力\(AC\)自动机.\(SAM\)等等五花八门 我这个蒟蒻在这里提供一种复杂度正确且常 ...

  5. [BZOJ2754] [SCOI2012]喵星球上的点名解题报告|后缀数组

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

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

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

  7. BZOJ2754 SCOI2012喵星球上的点名

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

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

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

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

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

随机推荐

  1. NFC标签

    2.4 NFC标签 NFC标签(以下也称tag)是一种带有NFC电路和天线的钱币大小的电子标签,见图2.1,小容量的标签售价约1元左右一枚. 基本标签类型有四种,以1至4来标识,各有不同的格式与容量. ...

  2. Solr 1.3 安装步骤

    可以通过以下三种方式之一设置   Solr   的主位置: 1.设置   java   系统属性   solr.solr.home   (没错,就是  solr.solr.home).    2.配置 ...

  3. [转] jQuery按键响应事件keypress对应的按键编码keycode

    原文地址:http://blog.csdn.net/chenhj1988918/article/details/7534922 keypress  api 文档:http://api.jquery.c ...

  4. js 无刷新分页代码

    /** * 分页事件处理 */function paging(){ $("#firstPage").click(function(){ //首页 var pageNo = getP ...

  5. mysql 账户操作

    1.授权 mysql> grant 权限1,权限2,…权限n on 数据库名称.表名称 to 用户名@用户地址 identified by ‘连接口令’; 权限1,权限2,…权限n代表selec ...

  6. 编程语言的发展趋势by Anders Hejlsberg

    这是Anders Hejlsberg在比利时TechDays 2010所做的开场演讲. 编程语言的发展非常缓慢,期间也当然出现了一些东西,例如面向对象等等,你可能会想,那么我么这么多年的努力都到哪里去 ...

  7. Spring in action笔记

    耦合的两面性     一方面代码耦合难以测试,会出现打地鼠式的bug特性(修复一个bug,引发另一个bug) 另一方面耦合又是必须的,不同的类必须要进行适当的交互,才能实现功能. bean的四种装配方 ...

  8. HA高可用配置

    HA 即 (high available)高可用,又被叫做双机热备,用于关键性业务. 简单理解就是,有两台机器A和B,正常是A提供服务,B待命闲置,当A宕机或服务宕掉,会切换至B机器继续提供服务. 下 ...

  9. MySQL在远程访问时非常慢的解决skip-name-resolve 并且出现 Reading from net

    转载:http://www.itokit.com/2012/0515/73932.html 服务器放在局域网内进行测试时,数据库的访问速度还是很快.但当服务器放到外网后,数据库的访问速度就变得非常慢. ...

  10. yii2 安装

    php版本必须是php5.4以上.记得配置php环境变量 1.下载https://github.com/yiisoft/yii2-app-advanced 2.php -r "readfil ...