P3879 [TJOI2010] 阅读理解
题面
英语老师留了 \(N\) 篇阅读理解作业,但是每篇英文短文都有很多生词需要查字典,为了节约时间,现在要做个统计,算一算某些生词都在哪几篇短文中出现过。
输入格式
第一行为整数 \(N\) ,表示短文篇数,其中每篇短文只含空格和小写字母。
按下来的 \(N\) 行,每行描述一篇短文。每行的开头是一个整数 \(L\) ,表示这篇短文由 \(L\) 个单词组成。接下来是 \(L\) 个单词,单词之间用一个空格分隔。
然后为一个整数 \(M\) ,表示要做几次询问。后面有 \(M\) 行,每行表示一个要统计的生词。
输出格式
对于每个生词输出一行,统计其在哪几篇短文中出现过,并按从小到大输出短文的序号,序号不应有重复,序号之间用一个空格隔开(注意第一个序号的前面和最后一个序号的后面不应有空格)。如果该单词一直没出现过,则输出一个空行。
提示说明
对于 \(30\%\) 的数据, \(1\le M\le 10^3\) 。
对于 \(100\%\) 的数据,\(1\le M\le 10^4\),\(1\le N\le 10^3\) 。
每篇短文长度(含相邻单词之间的空格)\(\le 5\times 10^3\) 字符,每个单词长度 \(\le 20\) 字符。
每个测试点时限 \(2\) 秒。
思路
这道题其实是可以用STL的。
首先,统计可以用 std::map
,对于一段有几个单词的问题,可以使用 std::set
。
其实就是 std::map
。
时间复杂度 \(O(N(\log \max\{L\}) + MN(\log^2 N))\)。好复杂
代码
#include
using namespace std;
int n,m;
map > dictionary;
int main(){
cin>>n;
for(int i=1,slen;i<=n;i++){
string s;
cin>>slen;
for(int j=1;j<=slen;j++){
cin>>s;
dictionary[s].insert(i);
}
}
cin>>m;
for(int i=1;i<=m;i++){
string word;
cin>>word;
if(dictionary.count(word)){
for(auto j:dictionary[word]){
cout<