UVa11732 "strcmp()" Anyone?

来源:互联网 发布:淘宝店铺一心好做吗 编辑:程序博客网 时间:2024/05/24 15:40

原题

题目传送

题解

用Trie把所有单词合起来,插入一次就统计一次这个单词和已插入的单词比较的次数。也就是相同部分前缀长度*2+1.但是注意两个完全相同的单词比如说a a需要比4次,因为最后的结束符号也是一样的,还有就是左儿子右兄弟表示法,好好学习QAQ。

代码

#include<queue>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=1000+10;const int maxnode=4000000+10;typedef long long ll;struct Trienode{    char ch;    int cnt,val;    Trienode *lc,*next;    Trienode(){        lc=next=NULL;        val=cnt=ch=0;    }};struct Trie{    Trienode *root;    Trie(){        root=new Trienode();    }    inline void clear(){        root=new Trienode();    }    inline ll insert(Trienode *p,char *s,int v){        ll ret=0;        int n=strlen(s);        for(int i=0;i<n;i++)        {            int x=0;            Trienode *k=p->lc,*wh=NULL;            for(;k;k=k->next)            {                if(k->ch==s[i])wh=k;                else x+=k->cnt;            }            k=wh;            if(!k)            {                k=new Trienode();                k->next=p->lc;                p->lc=k;                k->ch=s[i];            }            if(x) ret=ret+(i*2+1)*x;            if(i==n-1)             {                ret=ret+((i+1)*2+1)*k->cnt;                if(k->val) ret+=k->val;            }            else if(k->val) ret=ret+(2*(i+1)+1)*k->val;            k->cnt++;            p=k;        }        p->val+=v;        return ret;    }}trie;int kase=0,n;char s[maxn];void solve(){    trie.clear();    ll ans=0;    for(int i=1;i<=n;i++)    {        scanf("%s",s);        ans+=trie.insert(trie.root,s,1);    }    printf("Case %d: %lld\n",++kase,ans);    return ;}int main(){    while(scanf("%d",&n)==1&&n) solve();    return 0;}
0 0
原创粉丝点击