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 ...
随机推荐
- keepalived(2)- keepalived安装和配置
目录 1. keepalived安装配置 1.1 keepalived安装环境 1.2 keepalived日志文件 1.3 keepalived配置文件 2. keepalived配置 2.1 ke ...
- ACM算法竞赛代码模板(长期更新)
C++算法模板 基础算法 排序 快速排序 void quickSort(int q[], int l, int r) { if (l >= r) return; int i = l - 1, j ...
- 抽丝剥茧:详述一次DevServer Proxy配置无效问题的细致排查过程
事情的起因是这样的,在一个已上线的项目中,其中一个包含登录和获取菜单的接口因响应时间较长,后端让我尝试未经服务转发的另一域名下的新接口,旧接口允许跨域请求,但新接口不允许本地访问(只允许发布测试/生产 ...
- 经验分享:春招零Offer,5月份还有机会吗?
先说答案:5 月份依然有拿到 Offer 的机会. 5月份春招结束了吗? 对于应届大学生来说(也就是今年暑假毕业的学生),5 月中旬春招就陆续结束了,但是 5 月份会有很多补录的机会. 对于非应届的大 ...
- 安装 MySQL ZIP 版本
安装 MySQL 的 ZIP 版本相对于安装包版本稍微复杂一些,因为它需要手动解压和配置.以下是在 Windows 上安装 MySQL ZIP 版本的步骤: 下载 MySQL ZIP 文件: 前往 M ...
- 鸿蒙HarmonyOS实战-Stage模型(信息传递载体Want)
前言 应用中的信息传递是为了实现各种功能和交互.信息传递可以帮助用户和应用之间进行有效的沟通和交流.通过信息传递,应用可以向用户传递重要的消息.通知和提示,以提供及时的反馈和指导.同时,用户也可以通过 ...
- Mysql 存储引擎的区别以及索引查询失效的情况
存储引擎:就是指表在计算机上的存储方式.可以通过 SHOW ENGINES; 命令查询支持的存储引擎. alter table test engine= innodb/memory/myisam/ar ...
- Linux系统编程(十)线程池
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h& ...
- NOIP模拟59
T1 柱状图 解题思路 二分答案+线段树check 显然对于最后的限制,我们希望向上移的和向下移的柱子数尽量接近. 因此枚举每一个柱子当做最高的一个的时刻,二分找到一个当前最优解更新答案. 开两棵线段 ...
- 【论文笔记】R-CNN系列之代码实现
代码源码 前情回顾:[论文笔记]R-CNN系列之论文理解 整体架构 由三部分组成 (1)提取特征的卷积网络extractor (2)输入特征获得建议框rois的rpn网络 (3)传入rois和特征图, ...