当前位置: 代码迷 >> 综合 >> UVA11732 Trie (恢复训练课设练习)
  详细解决方案

UVA11732 Trie (恢复训练课设练习)

热度:77   发布时间:2024-02-24 14:30:45.0

题意:

给你n个字符串。要你两两进行比较。求总共的比较次数。
在这里插入图片描述

思路:

用trie去优化。
细心观察可以发现,可以边读入边计算ans。

  1. 每读入一个word进trie里时,就可以计算不过中间的逻辑关系要理清

  2. 本题结点的val,改为记录字符串的个数。

  3. 当insert一个word时,即遍历word时。假设当前结点为u,那么儿子为v。此时就可以计算答案。
    ans+=(val[u]-val【ch【u】【c】】) x (len-1) x 2+
    (val[u]-val【ch【u】【c】】)(这一步运用了容斥)
    化简一下
    ans+=(val[u]-val【ch【u】【c】】) x ((len-1) x 2+1)

  4. 最后遍历完word时,还要考虑一下,之前是否有和这个单词相同的单词。或者当前word是之前读入的前缀。这两种情况的答案是不同的。这里就加一个变量记录当前结点是几个字符串的结尾。

反思

中间的逻辑没理清楚,导致一直wa。。。qwq(康复训练还在继续)。

AC

#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#define For(i,x,y) for(int i=(x); i<=(y); i++)
using namespace std;
typedef long long ll;
const int maxnode=4000*1000+10;///最多有多少层
const int sigma_size=100;///字母的话就是26
struct Trie{
    int ch[maxnode][sigma_size];///ch[u][0]代表这个结点不存在int is_end[maxnode];ll val[maxnode];///结点的权值(相当于标记是否为一个字符串的最后一个元素)int sz;///结点总数void clear(){
    sz=1; memset(ch[0],0,sizeof(ch[0]));memset(val,0,sizeof(val));memset(is_end,0,sizeof(is_end)); }// Tire(){sz=1; memset(ch[0],0,sizeof(ch[0])); }///初始化第一个根结点int idx(char c){
    if(isalpha(c)){
    if(c>='a')return c-'a';///'a'的ascll码在后面else return c-'A'+26;}return c-'0'+52;}/////插入字符串s,附加信息v(权值)。注意v必须非0,因为0代表“本结点不是单词结点”void insert(char *s, ll &tmp){
    int u=0, len_s=strlen(s);tmp=0;for(int i=0; i<len_s; i++){
    int c=idx(s[i]);if(!ch[u][c]){
    ///结点不存在memset(ch[sz],0,sizeof(ch[sz]));val[sz]=0;///中间结点的附加信息为0.ch[u][c]=sz++;///新建结点}tmp+=(val[u]-val[ch[u][c]])*2*i+(val[u]-val[ch[u][c]]);val[u]++;u=ch[u][c];///往下走。//cout<<u<<endl;}// cout<<tmp<<endl;tmp+=(ll)is_end[u]*(len_s+1)*2;tmp+=(val[u]-is_end[u])*(2*len_s+1);is_end[u]++;val[u]++;///最后一个字符的附加信息为v。}
}trie;
int num;
ll work(){
    char s[1100];ll ans=0,tmp;For(i,1,num){
    scanf("%s", s);trie.insert(s,tmp);ans+=tmp;}return ans;
}
int main()
{
    int kase=0;while(scanf("%d", &num)&&num){
    trie.clear();printf("Case %d: %lld\n", ++kase,work());}return 0;
}
/* 2 a b 4 cat hat mat sir 0 */