zoukankan      html  css  js  c++  java
  • 单词(bzoj 3172)

    Description

    某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。

    Input

    第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6

    Output

    输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。

    Sample Input

    3
    a
    aa
    aaa

    Sample Output

    6
    3
    1
    /*
      在构建trie树时,统计每个节点出现的次数。
      从前向后DP,用一个单词的后缀的次数来更新前缀的次数。
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define N 1000010
    using namespace std;
    int a[N][26],point[N],sum[N],q[N],w[210],h,t,n,size=1;
    char s[N];
    void insert(int &x){
        int len=strlen(s),now=1;
        for(int i=0;i<len;i++){
            int t=s[i]-'a';
            if(!a[now][t])a[now][t]=++size;
            now=a[now][t];
            sum[now]++;
        }
        x=now;
    }
    void acmach(){
        h=0;t=1;q[1]=1;
        while(h<t){
            int now=q[++h];
            for(int i=0;i<=25;i++){
                if(!a[now][i])continue;
                int k=point[now];
                while(!a[k][i])k=point[k];
                point[a[now][i]]=a[k][i];
                q[++t]=a[now][i];
            }
        }
    }
    void solve(){
        for(int i=t;i;i--)sum[point[q[i]]]+=sum[q[i]];
        for(int i=1;i<=n;i++)printf("%d
    ",sum[w[i]]);
    }
    int main(){
        scanf("%d",&n);
        for(int i=0;i<=25;i++)a[0][i]=1;
        for(int i=1;i<=n;i++){
            scanf("%s",&s);
            insert(w[i]);
        }
        acmach();solve();
        return 0;
    }
  • 相关阅读:
    事务
    触发器
    SQL 存储过程
    SQL 视图 索引
    SQL 函数
    SQL查询语句练习
    SQL约束
    SQL Server 数据的添加修改删除和查询
    The type ProxyGenerator is not accessible due to restriction on required library问题的解决
    ==与equals
  • 原文地址:https://www.cnblogs.com/harden/p/6247718.html
Copyright © 2011-2022 走看看