hihoCoder #1656 前后缀查询
题目大意
给定 $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」。
hihoCoder #1656 前后缀查询的更多相关文章
- codeforces 579D D. "Or" Game(前后缀+贪心)
题目链接: D. "Or" Game time limit per test 2 seconds memory limit per test 256 megabytes input ...
- Objective-C 【NSString-字符串比较&前后缀检查及搜索】
———————————————————————————————————————————NSString 字符串比较 #import <Foundation/Foundation.h> vo ...
- poj 2752 Seek the Name, Seek the Fame【KMP算法分析记录】【求前后缀相同的子串的长度】
Seek the Name, Seek the Fame Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14106 Ac ...
- [LeetCode] Prefix and Suffix Search 前后缀搜索
Given many words, words[i] has weight i. Design a class WordFilter that supports one function, WordF ...
- Hibernate给表和字段设置前后缀及分隔符
在<一口一口吃掉Hibernate(一)--使用SchemaExport生成数据表>中介绍了如何生成数据表.但是这只是最基本的.hibernate在生成或者操作数据库时,会受一些限制.比如 ...
- HDU 2594(求最长公共前后缀 kmp)
题意是在所给的两个字符串中找最长的公共前后缀,即第一个字符串前缀和第二个字符串后缀的最长相等串. 思路是将两个字符串拼接在一起,然后直接套用 kmp 算法即可. 要注意用 next 会报编译错误,改成 ...
- poj 2752 求一个字符串所有的相同前后缀
求一个字符串所有的相同前后缀Sample Input ababcababababcababaaaaaSample Output 2 4 9 181 2 3 4 5 #include <iostr ...
- HDU 2594 最长相同前后缀
Sample Inputclintonhomerriemannmarjorie Sample Output0rie 3 输入两个字符串 ,求最长相同前后缀直接把两个字符串连接在一起求next就行了,唯 ...
- python 删除2天前后缀为.log的文件
python脚本 删除2天前后缀为.log的文件 #!/usr/local/python/bin/python #-*-coding=utf8 -*- import time import os,sy ...
随机推荐
- python基础教程总结15——2 画幅好画
要求:从Internet上下载数据文件: 分析数据文件并提取感兴趣的部分 工具:图形生成包(ReportLab,PYX等) 数据:太阳黑子和射电辐射流量(http://services.swpc.n ...
- Object Modeling
https://developer.apple.com/library/content/documentation/General/Conceptual/CocoaEncyclopedia/Objec ...
- python 基础之while无限循环
用户登录程序 username = "chenxi" passwed = "testki" counter = 0 while counter < 3: ...
- 2018.5.4 AndroidStudio遇到的问题
新建项目初出现异常报错 Error:Execution failed for task ':app:preDebugAndroidTestBuild'. > Conflict 发生这类型的错误, ...
- pysql用类进行封装
pyMySQL用类进行封装 class SqlHelper(object): def __init__(self): self.connect() def connect(self): self.co ...
- C语言单链表的实现
// // main.c // gfhjhgdf // // Created by chenhao on 13-12-23. // Copyright (c) 2013年 chenhao. A ...
- .NET 中,编译器直接支持的数据类型称为基元类型(primitive type).基元类型和.NET框架类型(FCL)中的类型有直接的映射关系.
.NET 中,编译器直接支持的数据类型称为基元类型(primitive type).基元类型和.NET框架类型(FCL)中的类型有直接的映射关系. The primitive types are Bo ...
- git使用stash存储相关操作
git stash 将当前修改存储起来 git stash apply 恢复最近一次存储 git stash apply stash@{2} 恢复某一次存储 git stash list 查看存储列 ...
- mysql 添加数据如果数据存在就更新ON DUPLICATE KEY UPDATE和REPLACE INTO
#下面建立game表,设置name值为唯一索引. CREATE TABLE `game` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar( ...
- 【mysql】【windows】MySQL 服务无法启动,服务没有报告任何错误,请键入 NET HELPMSG 3534 以获得更多的帮助。
成功安装以后,启动MySQL,输入: net start mysql 提示: ”MySQL 服务无法启动,服务没有报告任何错误,请键入 NET HELPMSG 3534 以获得更多的帮助.” 查了下, ...