zoukankan      html  css  js  c++  java
  • UVa11732 "strcmp()" Anyone?(Trie树+孩子兄弟表示法)

    我的做法是先建字典树,统计每个结点出现次数和相同字符串个数,每个结点对答案的贡献就是2*C(次数,2),然后再分别讨论相同字符串和不同字符串对答案的贡献。

    另外这题主要就是Trie树的孩子兄弟表示法:

    因为数据范围,4000个字符串每个字符串长度1000且字符的范围有62个,用孩子链表表示法最坏,4000*1000*62,再*4Byte,近1GB的内存,太大了,有许多空指针浪费空间。

    所以需要用孩子兄弟表示法压缩字典树,4000*1000*2,左孩子右兄弟,用时间换空间。

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 char key[4100000];
     5 int ch[4100000][2],cnt[4100000],flag[4100000],tn;
     6 void insert(char *s){
     7     int x=0;
     8     for(int i=0; s[i]; ++i){
     9         if(ch[x][0]==0){
    10             ch[x][0]=++tn;
    11             x=ch[x][0];
    12             key[x]=s[i];
    13             ++cnt[x];
    14             continue;
    15         }
    16         for(x=ch[x][0]; key[x]!=s[i] && ch[x][1]; x=ch[x][1]);
    17         if(key[x]!=s[i]){
    18             ch[x][1]=++tn;
    19             x=ch[x][1];
    20             key[x]=s[i];
    21             ++cnt[x];
    22         }else ++cnt[x];
    23     }
    24     ++flag[x];
    25 }
    26 
    27 int main(){
    28     int t=0,n;
    29     char str[1111];
    30     while(~scanf("%d",&n) && n){
    31         tn=0;
    32         memset(key,0,sizeof(key));
    33         memset(ch,0,sizeof(ch));
    34         memset(cnt,0,sizeof(cnt));
    35         memset(flag,0,sizeof(flag));
    36         while(n--){
    37             scanf("%s",str);
    38             insert(str);
    39         }
    40         long long res=0;
    41         int tot=0,sn=0;
    42         for(int i=1; i<=tn; ++i){
    43             res+=(cnt[i]-1)*cnt[i];
    44             if(flag[i]){
    45                 res+=(flag[i]-1)*flag[i];
    46                 tot+=flag[i];
    47             }
    48         }
    49         long long tmp=0;
    50         for(int i=1; i<=tn; ++i){
    51             if(flag[i]) tmp+=(tot-flag[i])*flag[i];
    52         }
    53         res+=tmp>>1;
    54         printf("Case %d: %lld
    ",++t,res);
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    Linux(CentOS)下安装OMNet++
    Linux(CentOS)安装JDK
    给电脑安装Linux系统(CentOS)
    OmNet++遇到的问题
    数论倒数总结
    [AHOI2007]密码箱
    [AHOI2005]约数研究
    Spark scala groupBy后求和
    Scala Seq创建简单的Spark DataFrame
    Spark DataFrame分组后选取第一行
  • 原文地址:https://www.cnblogs.com/WABoss/p/5162819.html
Copyright © 2011-2022 走看看