973 字
5 分钟
String STL set map Trie
描述
硬盘中里面有n个文件,文件从1到n标号,每个文件可以用若干个数字序列来表示,而且每个文件存在一个重要值。现在请你完成一个搜索系统,有m 个搜索的操作,如果一个文件中有以这个数字序列为前缀的数字序列,那么这个文件会被搜索到,现在我们想知道会有多少个文件被搜索到,以及这 些文件中重要值前k小的是哪些。
输入
第一行两个数n,m。 接下来n行是对每个文件的描述(标号依次是1到n): 每行的前两个数字分别为描述这个文件的数字序列个数t和文件的重要值v。 接下来有t组数。 每组数先有一个数l,表示这个数字序列的长度。 接下来有l个数,表示这个序列。 接下来m行表示m个搜索操作: 每行的前两个数字分别为搜索数k和前缀长度l。 接下来l个数是这个前缀的数字序列。
输出
共m行。 每行来表示搜索的结果: 首先你需要输出有多少个文件会被搜索到。 接下来你需要输出k个数,依次是重要值前k小的标号(根据重要值由小到大输出,重要值相同时,标号小的排在前面)。 如果搜索到的文件数p比k小,那么你只需要输出p个,如果没有搜索到文件就不用输出了。
样例输入
5 5
1 1 5 1 2 3 4 5
1 2 5 1 2 4 5 3
1 8 5 2 1 4 3 2
1 9 5 2 1 8 5 2
1 1 5 1 2 3 4 5
2 2 1 2
3 2 1 2
4 2 1 2
4 2 2 1
1 2 2 1
样例输出
3 1 5
3 1 5 2
3 1 5 2
2 3 4
2 3
数据范围和约定
- 对于20%的数据
0<n,m<=50
每次询问k无限制
0<重要值<=10^9
0<数字序列中的数字<=10
所有文件数字序列长度之和<=500
所有询问前缀数字序列长度之和<=500 - 对于另外20%的数据
0<n,m<=50
每次询问k无限制
0<重要值<=10^9
0<数字序列中的数字<=10^9
所有文件数字序列长度之和<=500
所有询问前缀数字序列长度之和<=500 - 对于另外20%的数据
0<n,m<=510^4
每次询问k=1或k=2
0<重要值<=10^9
0<数字序列中的数字<=10
所有文件数字序列长度之和<=210^5
所有询问前缀数字序列长度之和<=2*10^5 - 对于剩下的数据
0<n,m<=510^4
每次询问k无限制
0<重要值<=10^9
0<数字序列中的数字<=10^9
所有文件数字序列长度之和<=210^5
所有询问前缀数字序列长度之和<=2*10^5
#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <map>#include <set>#include <ctime>using namespace std;vector<int> l;struct Improtant{ int i, Imp; bool operator<(const Improtant &a) const { return Imp == a.Imp ? i < a.i : Imp < a.Imp; }} number[50005];struct Trie{ map<int, Trie *> mp; set<Improtant> mark;} * root;void insert(int x){ Trie *rt = root; rt->mark.insert(number[x]); for (int i = 0; i < l.size(); i++) { if (!rt->mp[l[i]]) rt->mp[l[i]] = new Trie; rt = rt->mp[l[i]]; rt->mark.insert(number[x]); }}void Query(int k){ Trie *rt = root; for (int i = 0; i < l.size(); i++) { if (rt->mp[l[i]] == NULL) { printf("0\n"); return; } rt = rt->mp[l[i]]; } set<Improtant>::iterator it = rt->mark.begin(); printf("%d ", rt->mark.size()); for (int i = 1; i <= k && it != rt->mark.end(); i++, it++) { printf("%d ", it->i); } printf("\n"); return;}int main(){#ifdef Mine freopen("1.in", "r", stdin);#else freopen("string.in", "r", stdin);#endif freopen("string.out", "w", stdout); int n, m; root = new Trie; scanf("%d%d", &n, &m); int t, s, a; for (int i = 1; i <= n; i++) { number[i].i = i; scanf("%d%d", &t, &number[i].Imp); while (t--) { scanf("%d", &s); l.clear(); for (int j = 1; j <= s; j++) { scanf("%d", &a); l.push_back(a); } insert(i); } } int k; for (int i = 1; i <= m; i++) { scanf("%d%d", &k, &s); l.clear(); for (int j = 1; j <= s; j++) { scanf("%d", &a); l.push_back(a); } Query(k); } //printf("%lf",(double)clock()/CLOCKS_PER_SEC);}
String STL set map Trie
https://www.nekomio.com/posts/33/