题目大意

给定 $n$($n\le 50000$) 个由小写英文字母构成的字符串,每个串的长度不超过 10,每个串有一个权值 $v$ ($1\le v\le 100000$)。

回答 $m$($m\le 50000$)组询问,询问格式为两个字符串 $p,s$,求输入中满足「以 $p$ 为前缀并且以 $s$ 为后缀」的串的最大权值。

解法

我的做法:字典树套字典树。

标程做法:将输入中长为 $k$ 的字符串变成 $k$ 个新字符串;

例子:

abc 变成

a#cba

ab#cba

abc#cba

用所有新串建一棵字典树。

对于查询 $p,s$ ,在字典树中查询 $p+`\#`+ \mathrm{reverse}(s)$ 。

实现要点

字典树的每个节点开长为 26 的数组(可能)会 MLE,可以用「左儿子-右兄弟」方式建树。

Highlights

我写了一个字典树模板类,自认为很 fancy。

#include <bits/stdc++.h>
using namespace std;
using ll = long long; template<class T>
struct trie{
struct node{
char x;
size_t l, r;
}; using val_t = T;
vector<pair<node,val_t>> a; val_t _null; trie(){
a.push_back({});
}
size_t size()const {
return a.size();
}
// LC-RS: left-child right-sibling
size_t get_child(size_t i, char x)const{
for(i=a[i].first.l; ; i=a[i].first.r){
if(a[i].first.x == x || !a[i].first.r)
return i;
}
} template <typename lambda>
void insert(const string &s, lambda &&upd){
size_t i=0;
upd(a[i].second);
for(auto x: s){
auto _i = get_child(i, x);
if(a[_i].first.x == x)
i = _i;
else{
if(!_i){
a[i].first.l=a.size();
}
else{
a[_i].first.r=a.size();
}
i = a.size();
a.push_back({});
a.back().first.x = x;
}
upd(a[i].second);
}
} const val_t &operator[](const string &s)const {
size_t i = 0;
for(auto x: s){
i = get_child(i, x);
if(a[i].first.x != x)
return _null;
}
return a[i].second;
}
}; trie<trie<int>> a; int main(){
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(nullptr); int n, m;
cin >> n >> m; for(int i=0; i<n; i++){
string s;
int v;
cin >> s >> v; auto upd = [s, v](auto &val)mutable {
reverse(s.begin(), s.end());
val.insert(s, [v](auto &val){val=max(val, v);});
}; a.insert(s, upd);
} for(int i=0; i<m; i++){
string pre, suf;
cin >> pre >> suf;
reverse(suf.begin(), suf.end()); // error-prone
int res = a[pre][suf];
cout << (res? res: -1) << '\n';
}
return 0;
}

代码中用到了 generic lambda:

auto upd = [s, v](auto &val)mutable {
reverse(s.begin(), s.end());
val.insert(s, [v](auto &val){val=max(val, v);});
};

这是 C++ 14 引入的新特性,如果你使用的编译器尚不支持 C++ 14,可以将「lambda 表达式」改成「generic functor」。

最新文章

  1. 13.KVM安装之网桥
  2. BZOJ3175 Tjoi2013 攻击装置(二分图匹配)
  3. shell小细节
  4. [iOS UI进阶 - 4.0] 涂鸦app Demo
  5. SQL Server内存性能分析
  6. 面试经典算法题集锦——《剑指 offer》小结
  7. 杭电ACM2022--发工资咯:)
  8. java关键字保留字
  9. swagger结合dubbo的rest服务测试
  10. switch与if语句的应用
  11. HashMap内部结构及实现原理
  12. 环境部署(九):linux下安装python+chrome+Xvfb
  13. jquery 设置cookie、删除cookie、获取cookie
  14. ecCodes 学习 利用ecCodes fortran90 api对GRIB文件进行读写
  15. 纯css控制文字2行显示多余部分隐藏
  16. Lemon OA第4篇:常用功能
  17. Linux之常用命令
  18. Kubernetes学习之路(十六)之存储卷
  19. TP3.2批量上传文件(图片),解决同名冲突问题
  20. java分布式(一)

热门文章

  1. C#去掉字符串最后面的一个标点符号的写法
  2. 四、filter和find函数的区别
  3. CentOS配置主机名和主机映射
  4. Java 吃金币游戏设计与制作,下载版后补,代码没问题
  5. HTML与XHTML区别
  6. 2019.5.18-5.19 ACM-ICPC 全国邀请赛(西安)赛后总结
  7. poj3525 Most Distant Point from the Sea
  8. Ubuntu 18.04 下用命令行安装Sublime
  9. C++输入密码不显示明文
  10. jquery中arrt()和prop()的区别