UVA

来源:互联网 发布:java模式 编辑:程序博客网 时间:2024/06/11 02:40

题解思路:用字典树模板加记录一下上一个状态剩余的字母个数

然后进入的个数是v[u]没有进入的个数就是pre[u]

题目链接

#include<cstring>#include<cstdio>#include<iostream>#include<cctype>#include<algorithm>#define mes(s) memset(s,0,sizeof(s))typedef long long int ll;using namespace std;const int mx = 4002*1000;struct trie{int ch[mx][63];int v[mx];int sum;int sz;void init(){ sz = 1, mes(ch[0]),mes(v),sum = 0;}int idx(char c){if(isdigit(c))return c-'0';else if(islower(c))return c-'a'+10;else if(isupper(c))return c-'A'+36;elsereturn 62;}void insert(char *s){int u = 0,len = strlen(s);sum++;for(int i = 0; i <= len; i++){int d = idx(s[i]);if(!ch[u][d]){mes(ch[sz]);ch[u][d] = sz;sz++;} u = ch[u][d];  v[u]++;}}int find(char *s){int u = 0,len = strlen(s);int ans = 0;int pre = sum;for(int i = 0; i <= len; i++){int d = idx(s[i]);if(!ch[u][d])return ans += pre;u = ch[u][d];ans += 2*v[u];  //进入的个数加上判断是否为s[i]是否为'\0'所以次数要乘于2ans += pre-v[u];pre = v[u];}return ans;}}word;int main(){int n;int casei = 1;char s[2000];while(cin>>n&&n){word.init();ll ans = 0;for(int i = 1; i <= n; i++){scanf("%s",s);ans += word.find(s);word.insert(s);}printf("Case %d: %lld\n",casei++,ans);}return 0;}


0 0
原创粉丝点击