题面
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 ",dfs(1)); }