UVA - 11732 字典树

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

然后进入的个数是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;
		else
			return 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'所以次数要乘于2
			ans += 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值