P9196 题解
来一份线性时间的题解。
考虑先解决前缀限制,显然可以直接把字符串和询问全部搬到 Trie 树上,问题就变成了查询一个子树内满足后缀限制的字符串数量。
接着考虑 Trie 树合并,具体地,把后缀限制以及字符串挂在单词节点上,接着遍历整个 Trie 每到一个节点就把这个节点的儿子的所有 Trie 树合并并将这个节点挂着的字符串插入,随后回答询问,当然这个 Trie 树要从末位插入解决后缀限制。
由于每进行一次合并操作就会减少一个 Trie 上的节点又因为节点数量是 \(O(\sum |S_i| + |P_i| + |Q_i|)\) 的所以复杂度就是线性的。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e6 + 114;
struct Big_Trie {
char c;
int ch[4];//A G U C
} tr1[maxn];
int answer[maxn];
int tot1, rt1;
struct Small_Trie {
char c;
int ch[4];//A G U C
int cnt;//单词节点数量
int sz;
} tr2[maxn];
int tot2;
int rt2[maxn];
int merge(int a, int b) {
if (a == 0 || b == 0)
return a + b;
tr2[a].ch[0] = merge(tr2[a].ch[0], tr2[b].ch[0]);
tr2[a].ch[1] = merge(tr2[a].ch[1], tr2[b].ch[1]);
tr2[a].ch[2] = merge(tr2[a].ch[2], tr2[b].ch[2]);
tr2[a].ch[3] = merge(tr2[a].ch[3], tr2[b].ch[3]);
tr2[a].cnt += tr2[b].cnt;
tr2[a].sz = tr2[tr2[a].ch[0]].sz + tr2[tr2[a].ch[1]].sz + tr2[tr2[a].ch[2]].sz + tr2[tr2[a].ch[3]].sz +
tr2[a].cnt;
return a;
}
void insert(int &cur, string &s) {
if (cur == 0)
cur = ++tot2;
if (s.size() == 0) {
tr2[cur].cnt++;
tr2[cur].sz = tr2[tr2[cur].ch[0]].sz + tr2[tr2[cur].ch[1]].sz + tr2[tr2[cur].ch[2]].sz +
tr2[tr2[cur].ch[3]].sz + tr2[cur].cnt;
return ;
} else if (s[s.size() - 1] == 'A')
s.pop_back(), insert(tr2[cur].ch[0], s);
else if (s[s.size() - 1] == 'G')
s.pop_back(), insert(tr2[cur].ch[1], s);
else if (s[s.size() - 1] == 'U')
s.pop_back(), insert(tr2[cur].ch[2], s);
else if (s[s.size() - 1] == 'C')
s.pop_back(), insert(tr2[cur].ch[3], s);
tr2[cur].sz = tr2[tr2[cur].ch[0]].sz + tr2[tr2[cur].ch[1]].sz + tr2[tr2[cur].ch[2]].sz +
tr2[tr2[cur].ch[3]].sz + tr2[cur].cnt;
}
int query(int cur, string &s) {
if (cur == 0)
return 0;
else if (s.size() == 0) {
return tr2[cur].sz;
} else if (s[s.size() - 1] == 'A') {
s.pop_back();
return query(tr2[cur].ch[0], s);
} else if (s[s.size() - 1] == 'G') {
s.pop_back();
return query(tr2[cur].ch[1], s);
} else if (s[s.size() - 1] == 'U') {
s.pop_back();
return query(tr2[cur].ch[2], s);
} else if (s[s.size() - 1] == 'C') {
s.pop_back();
return query(tr2[cur].ch[3], s);
}
return 0;
}
vector<string> str[maxn];
void Ins_str(int &cur, string &s, string &Suf) {
if (cur == 0)
cur = ++tot1;
if (s.size() == 0) {
str[cur].push_back(Suf);
return ;
} else if (s[s.size() - 1] == 'A')
s.pop_back(), Ins_str(tr1[cur].ch[0], s, Suf);
else if (s[s.size() - 1] == 'G')
s.pop_back(), Ins_str(tr1[cur].ch[1], s, Suf);
else if (s[s.size() - 1] == 'U')
s.pop_back(), Ins_str(tr1[cur].ch[2], s, Suf);
else if (s[s.size() - 1] == 'C')
s.pop_back(), Ins_str(tr1[cur].ch[3], s, Suf);
}
vector< pair<string, int>> Q[maxn];
void Ins_ask(int &cur, string &s, string &Suf, int id) {
if (cur == 0)
cur = ++tot1;
if (s.size() == 0) {
Q[cur].push_back(make_pair(Suf, id));
return ;
} else if (s[s.size() - 1] == 'A')
s.pop_back(), Ins_ask(tr1[cur].ch[0], s, Suf, id);
else if (s[s.size() - 1] == 'G')
s.pop_back(), Ins_ask(tr1[cur].ch[1], s, Suf, id);
else if (s[s.size() - 1] == 'U')
s.pop_back(), Ins_ask(tr1[cur].ch[2], s, Suf, id);
else if (s[s.size() - 1] == 'C')
s.pop_back(), Ins_ask(tr1[cur].ch[3], s, Suf, id);
}
void dfs(int cur) {
if (cur == 0)
return ;
dfs(tr1[cur].ch[0]), rt2[cur] = merge(rt2[cur], rt2[tr1[cur].ch[0]]);
dfs(tr1[cur].ch[1]), rt2[cur] = merge(rt2[cur], rt2[tr1[cur].ch[1]]);
dfs(tr1[cur].ch[2]), rt2[cur] = merge(rt2[cur], rt2[tr1[cur].ch[2]]);
dfs(tr1[cur].ch[3]), rt2[cur] = merge(rt2[cur], rt2[tr1[cur].ch[3]]);
for (string now : str[cur]) {
insert(rt2[cur], now);
}
for (pair<string, int> now : Q[cur]) {
answer[now.second] = query(rt2[cur], now.first);
}
}
int n, m;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
string s, rs;
cin >> s;
for (int i = s.size() - 1; i >= 0; i--)
rs.push_back(s[i]);
Ins_str(rt1, rs, s);
}
for (int i = 1; i <= m; i++) {
string p, q, rp;
cin >> p >> q;
for (int i = p.size() - 1; i >= 0; i--)
rp.push_back(p[i]);
Ins_ask(rt1, rp, q, i);
}
dfs(rt1);
for (int i = 1; i <= m; i++)
cout << answer[i] << '\n';
}
P9196 题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
- JSOI2016R3 瞎BB题解
题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...
随机推荐
- phpstudy8.1安装与配置
环境: window10 phpstudy8.1.1.3 Vmware安装centos7.6 使用场景 window10安装mysql和redis 在Vmware安装centos7.6 桥接模式上网 ...
- 06. rails gem 安装mysql
修改Gamefile Gamefile 里添加 gem 'mysql2' 执行命令行 bundle 可以看到下图片上已经安装好依赖了 修改配置文件 修改config/database.yml文件 # ...
- Ubuntu的apt-get/yarm/wget命令详解
目录 一.查看本机是否安装软件 二.apt-get 三.yum 四.wget apt-cache和apt-get是apt包的管理工具, 他们根据/etc/apt/sources.list里的软件源地址 ...
- WEB集群 - LNMT集群架构部署zrlog
目录 1. 集群环境说明 2. NFS部署 3. mysql部署 4. redis部署 5. tomcat部署 6. nginx负载均衡部署 7. 客户端访问 8. tomcat+redis实现会话共 ...
- 记一次线上Redis内存占用过高、大Key问题的排查
问题背景 在一个风和日丽的下午,公司某项目现场运维同学反馈,生产环境3个Redis的Sentinel集群节点内存占用都很高,达到了17GB的内存占用量. 稍加思索,应该是某些Key的Value数据体量 ...
- cesium问题-关于不同时间模型亮度不一致问题
项目中遇到发布的bim模型在当天不同时间的模型亮度发生变化,尤其是晚上的时候会出现模型很暗.尴了个尬,一度怀疑是自己眼睛有问题,连续几天出现同样的情况,想到可能是时间问题导致的模型亮度不同,于是测试了 ...
- 网络数据流分析工具TcpEngine V1.0.0教程-1
概述 目前主流的网络数据分析工具主要有两类,一类是http协议分析工具,如fiddler,这类工具擅长对字符串类型协议分析:另一类是原始网络数据包的监听分析,如Wireshark,这类工具擅长分析网络 ...
- .NET周刊【5月第1期 2024-05-05】
国内文章 一个开源轻量级的C#代码格式化工具(支持VS和VS Code) https://www.cnblogs.com/Can-daydayup/p/18164905 CSharpier是一个开源. ...
- go高并发之路——启航
工作7年有余了,B端和C端业务都做过不少,打算整理分享一些自己在实际工作中所遇到的高并发的场景和解决方案,也是对自己本人职业生涯中的一些经验的总结和感悟.与其他博文略有不同的是,这些基本上都是自己实际 ...
- uniapp-vue3-oadmin手机后台实例|vite5.x+uniapp多端仿ios管理系统
原创vue3+uniapp+uni-ui跨端仿ios桌面后台OA管理模板Uni-Vue3-WeOS. uniapp-vue3-os一款基于uni-app+vite5.x+pinia等技术开发的仿ios ...