zoukankan      html  css  js  c++  java
  • BZOJ2780: [Spoj]8093 Sevenk Love Oimaster(广义后缀自动机,Parent树,Dfs序)

    Description

    Oimaster and sevenk love each other.
    But recently,sevenk heard that a girl named ChuYuXun was dating with oimaster.As a woman's nature, s
    evenk felt angry and began to check oimaster's online talk with ChuYuXun.    Oimaster talked with Ch
    uYuXun n times, and each online talk actually is a string.Sevenk asks q questions like this,    "how
     many strings in oimaster's online talk contain this string as their substrings?"
    有n个大串和m个询问,每次给出一个字符串s询问在多少个大串中出现过

    Input

    There are two integers in the first line, 
    the number of strings n and the number of questions q.
    And n lines follow, each of them is a string describing oimaster's online talk. 
    And q lines follow, each of them is a question.
    n<=10000, q<=60000 
    the total length of n strings<=100000, 
    the total length of q question strings<=360000

    Output

    For each question, output the answer in one line.

    Sample Input

    3 3
    abcabcabc
    aaa
    aafe
    abc
    a
    ca

    Sample Output

    1
    3
    1

    解题思路:

    利用Parent树的子节点都是父节点母串的性质,在大串的每个实节点打上标记,然后构建出这颗Parent树。

    那么我们的问题就变成了在一个Fail节点子树内不同颜色个数。

    像不像HH的项链?

    把Dfs序构建出来,离线树状数组就好了。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 const int N=200000;
      5 const int M=1000000;
      6 struct sant{
      7     int tranc[26];
      8     int len;
      9     int pre;
     10 }s[N];
     11 struct pnt{
     12     int hd;
     13     int col;
     14     int ind;
     15     int oud;
     16 }p[N];
     17 struct ent{
     18     int twd;
     19     int lst;
     20 }e[N];
     21 struct qust{
     22     int l,r;
     23     int ans;
     24     int no;
     25 }q[N];
     26 int siz;
     27 int fin;
     28 int n,Q;
     29 int cnt;
     30 int dfn;
     31 char tmp[N];
     32 int line[N];
     33 int lst[N];
     34 int phr[N];
     35 int col[N];
     36 void Insert(int c,int whic)
     37 {
     38     int nwp,nwq,lsp,lsq;
     39     nwp=++siz;
     40     p[nwp].col=whic;
     41     s[nwp].len=s[fin].len+1;
     42     for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)
     43         s[lsp].tranc[c]=nwp;
     44     if(!lsp)
     45         s[nwp].pre=1;
     46     else{
     47         lsq=s[lsp].tranc[c];
     48         if(s[lsq].len==s[lsp].len+1)
     49             s[nwp].pre=lsq;
     50         else{
     51             nwq=++siz;
     52             s[nwq]=s[lsq];
     53             s[nwq].len=s[lsp].len+1;
     54             s[nwp].pre=s[lsq].pre=nwq;
     55             while(s[lsp].tranc[c]==lsq)
     56             {
     57                 s[lsp].tranc[c]=nwq;
     58                 lsp=s[lsp].pre;
     59             }
     60         }
     61     }
     62     fin=nwp;
     63     return ;
     64 }
     65 void ade(int f,int t)
     66 {
     67     cnt++;
     68     e[cnt].twd=t;
     69     e[cnt].lst=p[f].hd;
     70     p[f].hd=cnt;
     71     return ;
     72 }
     73 void Dfs(int x)
     74 {
     75     p[x].ind=++dfn;
     76     phr[dfn]=x;
     77     col[dfn]=p[x].col;
     78     for(int i=p[x].hd;i;i=e[i].lst)
     79     {
     80         int to=e[i].twd;
     81         Dfs(to);
     82     }
     83     p[x].oud=dfn;
     84     return ;
     85 }
     86 bool cmp(qust x,qust y)
     87 {
     88     return x.r<y.r;
     89 }
     90 bool cmq(qust x,qust y)
     91 {
     92     return x.no<y.no;
     93 }
     94 int lowbit(int x)
     95 {
     96     return x&(-x);
     97 }
     98 void update(int pos,int x)
     99 {
    100     while(pos&&pos<=siz)
    101     {
    102         line[pos]+=x;
    103         pos+=lowbit(pos);
    104     }
    105     return ;
    106 }
    107 int query(int pos)
    108 {
    109     int ans=0;
    110     while(pos)
    111     {
    112         ans+=line[pos];
    113         pos-=lowbit(pos);
    114     }
    115     return ans;
    116 }
    117 int main()
    118 {
    119     fin=++siz;
    120     scanf("%d%d",&n,&Q);
    121     for(int i=1;i<=n;i++)
    122     {
    123         scanf("%s",tmp+1);
    124         fin=1;
    125         int len=strlen(tmp+1);
    126         for(int j=1;j<=len;j++)
    127             Insert(tmp[j]-'a',i);
    128     }
    129     for(int i=2;i<=siz;i++)
    130         ade(s[i].pre,i);
    131     Dfs(1);
    132     
    133     for(int i=1;i<=Q;i++)
    134     {
    135         scanf("%s",tmp+1);
    136         int root=1;
    137         int len=strlen(tmp+1);
    138         for(int j=1;j<=len;j++)
    139             root=s[root].tranc[tmp[j]-'a'];
    140         q[i].no=i;
    141         if(!root)
    142             continue;
    143         q[i].l=p[root].ind;
    144         q[i].r=p[root].oud;
    145     }
    146     std::sort(q+1,q+Q+1,cmp);
    147     int rr=1;
    148     for(int i=1;i<=Q;i++)
    149     {
    150         while(rr<=q[i].r)
    151         {
    152             if(!col[rr])
    153             {
    154                 rr++;
    155                 continue;
    156             }
    157             if(lst[col[rr]])
    158                 update(lst[col[rr]],-1);
    159             update(rr,1);
    160             lst[col[rr]]=rr;
    161             rr++;
    162         }
    163         rr--;
    164         if(!q[i].l)
    165             continue;
    166         q[i].ans=query(q[i].r)-query(q[i].l-1);
    167     }
    168     std::sort(q+1,q+Q+1,cmq);
    169     for(int i=1;i<=Q;i++)
    170         printf("%d
    ",q[i].ans);
    171     return 0;
    172 }
  • 相关阅读:
    MySQL 中随机抽样:order by rand limit 的替代方案
    mysql下distinct和group by区别对比
    MVC中实现多按钮提交(转)
    js的逻辑 OR 运算符- ||
    js 实现键盘记录 兼容FireFox和IE
    jquery扩展
    sp_executesql的用法
    MVC中,视图的Layout使用
    MVC4的过滤器
    MVC中的Repository模式
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10045971.html
Copyright © 2011-2022 走看看