【P1666】前缀单词

题面

https://www.luogu.org/problem/P1666

题解

这道题有点搞笑啊。

把单词插入到$trie$树上,对于$trie$树上的一个节点,设$f[x]$是这下面的所有单词节点的方案,有两种转移,一种是他不选,他的儿子自由组合,第二种是它选,它的儿子全都不选。

黑科技:$map trie$,并没有什么卵用。

#include<iostream>
#include<cstdio>
#include<map>

using namespace std;

struct node{
  int cnt;
  map<char,int> to;
} trie[2550];
int n,cnt;
long long f[2550];

void insert(string s){
  int now=1,l=s.size(),p;
  for (p=0;p<l;p++) {
    if (!trie[now].to.count(s[p])) trie[now].to[s[p]]=++cnt,now=cnt;
    else now=trie[now].to[s[p]];
  }
  trie[now].cnt++;
}

long long dfs(int x) {
  map<char,int>::iterator it;
  f[x]=1;
  for (it=trie[x].to.begin();it!=trie[x].to.end();it++) {
    f[x]*=dfs(it->second);
  }
  f[x]+=trie[x].cnt;
  return f[x];
}

int main(){
  int i;
  string st;
  cin>>n;
  cnt=1;
  for (i=1;i<=n;i++) {
    cin>>st;
    insert(st);
  }
  printf("%lld\n",dfs(1));
}

 

posted @ 2019-08-14 09:47  HellPix  阅读(174)  评论(0编辑  收藏  举报