[TJOI2010] 阅读理解 **STL**Tire树**
[TJOI2010] 阅读理解
题目链接:
https://www.luogu.com.cn/problem/P3879
题目描述
思路1 (STL大法)
对每个单词,用map
来映射存储它所在的短文编号
用set
的好处:
-------1. 存储直接自动排序,操作简单(忽略效率)
-------2. 可能一个单词在一篇短文中出现多次,这里去重操作set
自带实现
#include <iostream>
#include <set>
#include <map>
#include <string>
using namespace std;
map<string, set<int> > m;
int main() {
int n;
cin >> n;
for(int i = 1; i <= n; i++) {
int l;
cin >> l;
for(int j = 0; j < l; j++) {
string word;
cin >> word;
m[word].insert(i);
}
}
int p;
cin >> p;
while(p --) {
string t;
cin >> t;
if(m.count(t)) {
for(auto it = m[t].begin(); it != m[t].end(); it++)
cout << *it << " ";
cout << endl;
}
}
return 0;
}
思路二(Tire树)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include <bitset>
using namespace std;
int n,m;
char s[1001];
int l;
int tot=0;
int tri[300007][26];
bitset<1001> b[500007];
inline void insert(char *s,int x){
int rt=0;
for(int i=0;s[i];i++){
int v=s[i]-'a';
if(!tri[rt][v]){
tri[rt][v]=++tot;
}
rt=tri[rt][v];
}
b[rt][x]=1;
}
inline void query(char *s){
int rt=0;
for(int i=0;s[i];i++){
int v=s[i]-'a';
if(!tri[rt][v]){
cout<<' '<<endl;
return;
}
rt=tri[rt][v];
}
for(int i=1;i<=n;i++){
if(b[rt][i]==1){
cout<<i<<' ';
}
}
cout<<endl;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>l;
for(int j=1;j<=l;j++){
cin>>s;
insert(s,i);
}
}
cin>>m;
for(int i=1;i<=m;i++){
cin>>s;
query(s);
}
return 0;
}