zoukankan      html  css  js  c++  java
  • bzoj3172[Tjoi2013]单词

    bzoj3172[Tjoi2013]单词

    题意:

    某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。注意论文中单词之间是有分隔的。单词数≤200,长度≤1000000

    题解:

    先将每个单词插入trie,经过的节点的sum[i]++,然后求fail函数,求完后按BFS序倒过来维护sum[fail[i]]+=sum[i],最后输出第i个单词末尾字符节点的sum值。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define maxn 1000010
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 using namespace std;
     7 
     8 int ch[maxn][26],sum[maxn],pos[maxn],q[maxn],n,tot,fail[maxn]; char s[maxn];
     9 int insert(char *s){
    10     int l=strlen(s+1),x=0;
    11     inc(i,1,l){if(!ch[x][s[i]-'a'])ch[x][s[i]-'a']=++tot; x=ch[x][s[i]-'a']; sum[x]++;} return x;
    12 }
    13 void getfail(){
    14     int l=1,r=0; inc(i,0,25)if(ch[0][i])q[++r]=ch[0][i],fail[ch[0][i]]=0;
    15     while(l<=r){
    16         int x=q[l++];
    17         inc(i,0,25)if(ch[x][i]){
    18             int y=fail[x]; while(y&&!ch[y][i])y=fail[y];
    19             if(ch[y][i])fail[ch[x][i]]=ch[y][i]; q[++r]=ch[x][i];
    20         }
    21     }
    22     for(int i=r;i;i--)sum[fail[q[i]]]+=sum[q[i]];
    23 }
    24 int main(){
    25     scanf("%d",&n); tot=0; inc(i,1,n){scanf("%s",s+1); pos[i]=insert(s);}
    26     getfail(); inc(i,1,n)printf("%d
    ",sum[pos[i]]);
    27 }

    20160620

  • 相关阅读:
    STM32位带操作
    url参数 加密
    object.key 对象的键排序 可能出现的问题
    在vue项目中 获取容器的高度
    navigator 判断移动端是Android还是iOS
    Nginx下载地址
    Sublime Text3快捷键大全
    鼠标拖着元素飞
    g6 cavans
    vue img标签图片加载时 闪烁
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5701043.html
Copyright © 2011-2022 走看看