zoukankan      html  css  js  c++  java
  • bzoj3806: Neerc2011 Dictionary Size

    Description

    某国颁布了一本 n (n ≤ 10 000) 个单词的词典。单词长
    度不超过 40。 
    该国的造词法是这样的: 
    1: 词典中的单词是一个词。 
    2: 能分为两部分的,其中前一部分是一个词典词或者其非
    空前缀,后一部分是一个词典词或者其非空后缀的词。 
    求能造出的不相同的词汇数目。 

    将所有单词建成trie(A),反转后也建一颗trie(B),答案有三种情况

    1.原有单词

    2.原有单词的 长度>1的 严格前缀,且其最后一个字母是某单词的首字母

    3.不是原有单词或其前缀,但可以由前缀和后缀拼出(由于可能重复,对一个由两个单词拼出的串只统计后缀最短的一个,)

    分类统计即可

    #include<cstdio>
    #include<cstring>
    typedef long long i64;
    const int N=400007;
    i64 ans=0;
    char ss[10007][43];
    int n,ch[N][26],p1=1,p2=1,t0[26],t1[26],t2[26];
    int*ed[N];
    bool e[N],ee[26];
    int main(){
        scanf("%d",&n);
        for(int t=0;t<n;++t){
            scanf("%s",ss[t]);
            int l=strlen(ss[t]),w=1,c;
            for(int i=0;i<l;++i){
                c=ss[t][i]-'a';
                int &u=ch[w][c];
                if(!u)ed[u=++p1]=&u,++t1[c];
                w=u;
            }
            ee[c]=1;
            if(!e[w]){
                if(l>1)--t0[c];
                e[w]=1;
                ++ans;
            }
        }
        for(int i=0;i<26;++i)if(ch[1][i])--t1[i];
        for(int i=0;i<26;++i)if(ee[i])ans+=t0[i]+t1[i];
        for(int i=2;i<=p1;++i)*ed[i]=0;
        for(int t=0;t<n;++t){
            int l=strlen(ss[t]),w=1;
            for(int i=l-1;i>=0;--i){
                int c=ss[t][i]-'a',&u=ch[w][c];
                if(!u)u=++p2,++t2[c];
                w=u;
            }
        }
        ans+=i64(p1-1)*(p2-1);
        for(int i=0;i<26;++i)ans-=i64(t1[i])*t2[i];
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    Zabbix基本配置及监控主机
    利用XAG在RAC环境下实现GoldenGate自动Failover
    Oracle Database 12c Data Redaction介绍
    使用Oracle官方巡检工具ORAchk巡检数据库
    浅谈C# 多态
    Qt 操作Excel
    一个适用于任何继承于QObject的类的创建工厂
    QT5 控件增加背景图片(可缩放可旋转)的几种方法
    值得推荐和学习的C/C++框架和库
    gcc/g++编译
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7009399.html
Copyright © 2011-2022 走看看