UVa 11732 strcmp函数 trie树 左儿子右兄弟表示法

来源:互联网 发布:淘宝店怎么做百度推广 编辑:程序博客网 时间:2024/05/01 01:07

题意:

给出n个字符串, 计算两两比较的次数. 每次比较都需要比较(str1[i] == str2[i])和 (str1[i]== '\0'各一次).

分析:

边插入边统计,这样就刚好是两两比较一次的结果。如果先建树再深搜,那么就多比较了一次,/2就可以。

#include<cstdio>#include<cstring>typedef long long ll;const int N=4000*1000+10;ll ans;struct Trie{    int son[N],bro[N],val[N];    char ch[N];    int sz;    void clear(){sz=1;ch[0]=val[0]=bro[0]=son[0]=0;}    void insert(char *s)    {        int u=0,v,n=strlen(s);        for(int i=0;i<=n;i++){            for(v=son[u];v;v=bro[v]){                if(ch[v]==s[i])break;            }            if(!v){                v=sz++;                ch[v]=s[i];                bro[v]=son[u];                son[v]=0;                son[u]=v;                val[v]=0;            }            ans+=(val[u]-val[v])*(2*i+1);            if(i==n){                ans+=val[v]*(2*i+2);                val[v]++;            }            val[u]++;            u=v;        }    }};Trie trie;char s[1009];int main(){    int n,cas=0;    //freopen("f.txt","r",stdin);    while(~scanf("%d",&n)&&n){        trie.clear();        ans=0;        for(int i=0;i<n;i++){            scanf("%s",s);            trie.insert(s);        }        printf("Case %d: %lld\n",++cas,ans);    }    return 0;}


0 0
原创粉丝点击