[BZOJ4212]神牛的养成计划

试题描述

Hzwer 成功培育出神牛细胞,可最终培育出的生物体却让他大失所望......

后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变,原先决定神牛特征的基因序列都被破坏了,神牛hzwer很生气,但他知道基因突变的低频性,说不定还有以下优秀基因没有突变,那么他就可以用限制性核酸内切酶把它们切出来,然后再构建基因表达载体什么的,后面你懂的......

黄学长现在知道了 \(N\) 个细胞的 DNA 序列,它们是若干个由小写字母组成的字符串。一个优秀的基因是两个字符串 \(s_1\) 和 \(s_2\),当且仅当 \(s_1\) 是某序列的前缀的同时,\(s_2\) 是这个序列的后缀时,hzwer 认为这个序列拥有这个优秀基因。

现在黄学长知道了 \(M\) 个优秀基因 \(s_1\) 和 \(s_2\),它们想知道对于给定的优秀基因,有多少个细胞的 DNA 序列拥有它。

输入

第一行:\(N\),表示序列数

接下来 \(N\) 行,每行一个字符串,代表 \(N\) 个 DNA 序列,它们的总长为 \(L_1\)

接下来一个 \(M\),表示询问数

接下来 \(M\) 行,每行两个字符串 \(s_1\) 和 \(s_2\),由一个空格隔开,hzwer 希望你能在线回答询问,所以 \(s_1\) 等于“\(s_1\)”的所有字符按字母表的顺序向后移动 \(ans\) 位(字母表是一个环),\(ans\) 为上一个询问的答案,\(s_2\) 同理。例如 \(ans=2, “s_1”=qz\) 则 \(s_1=sb\)。对于第一个询问,\(ans=0\),\(s_1\) 和 \(s_2\) 的总长度为 \(L_2\)

输出

输出有 \(p\) 行,YesNo.

输入示例

10
emikuqihgokuhsywlmqemihhpgijkxdukjfmlqlwrpzgwrwozkmlixyxniutssasrriafu
emikuqihgokuookbqaaoyiorpfdetaeduogebnolonaoehthfaypbeiutssasrriafu
emikuqihgokuorocifwwymkcyqevdtglszfzgycbgnpomvlzppwrigowekufjwiiaxniutssasrriafu
emikuqihgokuorociysgfkzpgnotajcfjctjqgjeeiheqrepbpakmlixyxniutssasrriafu
emikuqihgokuorociysgfrhulymdxsqirjrfbngwszuyibuixyxniutssasrriafu
emikuqihgokuorguowwiozcgjetmyokqdrqxzigohiutssasrriafu
emikuqihgokuorociysgsczejjmlbwhandxqwknutzgdmxtiutssasrriafu
emikuqihgokuorociysgvzfcdxdiwdztolopdnboxfvqzfzxtpecxcbrklvtyxniutssasrriafu
emikuqihgokuorocsbtlyuosppxuzkjafbhsayenxsdmkmlixyxniutssasrriafu
emikuqihgokuorociysgfjvaikktsixmhaasbvnsvmkntgmoygfxypktjxjdkliixyxniutssasrriafu
10
emikuqihgokuorociysg yxniutssasrriafu
aiegqmedckgqknky eqpoowonnewbq
xfbdnjbazhdnhkhvb qrqgbnmlltlkkbtyn
bjfhrnfedlhrlolzfv qppxpoofxcr
zhdfpldcbjf stsidponnvnmmdvap
zhdfpldcbjfpjmjxdt gdstsidponnvnmmdvap
dlhjtphgfnjtnqnbhxr wxwmhtsrrzrqqhzet
bjfhrnfedlhrlolzfv frqppxpoofxcr
zhdfpldcbjf dponnvnmmdvap
ucyakgyxweakehes nondykjiiqihhyqvk

输出示例

4
7
3
5
5
1
3
5
10
4

数据规模及约定

\(N \le 2000\)

\(L_1 \le 2000000\)

\(M \le 100000\)

\(L_2 \le 2000000\)

题解

直接 \(O(NM)\) 哈希看上去复杂度是对的,但是大视野老爷机可能不是很资瓷……

其实并不明白 \(N\) 为什么不给到和 \(M\) 同阶,反正复杂度都是 \(O(L_1 + L_2)\) 的。

考虑建立 trie 树,这样直接解决了前缀的问题,我们可以发现所有合法的串一定都在 trie 树的某个子树中,而一个子树可以变成一段区间,那么我们就是要求一段区间内满足后缀是 \(s_2\) 的串有多少个。这样一来我们可以按照每个串在 trie 树中的 dfs 序,从小到大按反串建立可持久化 trie,这样对于一个区间直接就是两个版本的 trie 相减。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
#define rep(i, s, t) for(int i = (s), mi = (t); i <= mi; i++)
#define dwn(i, s, t) for(int i = (s), mi = (t); i >= mi; i--)int read() {int x = 0, f = 1; char c = getchar();while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }return x * f;
}#define maxl 2000010
#define maxln 2100010
#define maxa 26char S[maxl], S2[maxl];
int str[maxl], str2[maxl];struct Trie {int ToT, ch[maxl][maxa], fa[maxl], tot[maxl], clo, dl[maxl], dr[maxl], perm[maxl];Trie() { ToT = 1; }void Insert(char *S) {int n = strlen(S), u = 1;rep(i, 0, n - 1) {int x = S[i] - 'a';if(!ch[u][x]) fa[ch[u][x] = ++ToT] = u;u = ch[u][x];}tot[u]++;return ;}void build(int u) {perm[dl[u] = ++clo] = u;rep(c, 0, maxa - 1) if(ch[u][c]) build(ch[u][c]);dr[u] = clo;return ;}
} sol;struct RTrie {int ToT, ch[maxln][maxa], rt[maxln], siz[maxln];RTrie() { ToT = rt[0] = 1; }void Insert(int id, char *S, int v) {siz[++ToT] = siz[rt[id-1]] + v; memcpy(ch[ToT], ch[rt[id-1]], sizeof(ch[ToT])); rt[id] = ToT;// printf("siz[%d] = %d (+ %d)\n", ToT, siz[ToT], v);int n = strlen(S), u = rt[id];rep(i, 0, n - 1) {int x = S[i] - 'a';siz[++ToT] = siz[ch[u][x]] + v; memcpy(ch[ToT], ch[ch[u][x]], sizeof(ch[ToT])); ch[u][x] = ToT;u = ch[u][x];}return ;}int query(int *s1, int *s2, int l1, int l2) {int u = 1, vl, vr;rep(i, 0, l1 - 1) u = sol.ch[u][s1[i]];vl = rt[sol.dl[u]-1]; vr = rt[sol.dr[u]];// printf("%d: [%d, %d] %d %d | %d %d\n", u, sol.dl[u], sol.dr[u], vl, vr, siz[vl], siz[vr]);dwn(i, l2 - 1, 0) vl = ch[vl][s2[i]], vr = ch[vr][s2[i]];// printf("vl, vr: %d, %d %d %d\n", vl, vr, siz[vl], siz[vr]);return siz[vr] - siz[vl];}
} rsol;int main() {int n = read();rep(i, 1, n) scanf("%s", S), sol.Insert(S);sol.build(1);rep(i, 1, sol.ToT) {int u = sol.perm[i], l = 0;if(!sol.tot[u]) {rsol.rt[i] = rsol.rt[i-1];continue;}int v = sol.tot[u];while(u > 1) {rep(c, 0, maxa - 1) if(sol.ch[sol.fa[u]][c] == u){ S[l++] = c + 'a'; break; }u = sol.fa[u];}S[l] = 0;// printf("rsol.Insert(%d, %s)\n", i, S);rsol.Insert(i, S, v);}int q = read(), lstans = 0;while(q--) {scanf("%s%s", S, S2);int l = strlen(S), l2 = strlen(S2);rep(i, 0, l - 1) str[i] = (S[i] - 'a' + lstans) % maxa;rep(i, 0, l2 - 1) str2[i] = (S2[i] - 'a' + lstans) % maxa;printf("%d\n", lstans = rsol.query(str, str2, l, l2));}return 0;
}

转载于:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/8479408.html

[BZOJ4212]神牛的养成计划相关推荐

  1. BZOJ 4212: 神牛的养成计划

    4212: 神牛的养成计划 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 142  Solved: 30 [Submit][Status][Disc ...

  2. 4212: 神牛的养成计划

    4212: 神牛的养成计划 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 86  Solved: 20 [Submit][Status][Discu ...

  3. 神牛的养成计划---可持久化trie

    题目大意 给定n个由小写字母组成的字符串.现在有m个询问,每个询问指定两个字符串s1,s2.要求回答:在给定的n个字符串中,有多少个字符串s满足:s1是s的前缀且s2是s的后缀.强制在线! 数据范围 ...

  4. 正式启动|2020腾讯犀牛鸟云开发校园技术布道师养成计划

    为顺应信息技术行业发展趋势及人才需求,促进新时代云计算领域人才培养,在信息技术新工科产学研联盟的指导下,由腾讯云.腾讯高校合作和图灵教育联合主办,牛客网协办的2020腾讯犀牛鸟云开发校园技术布道师养成 ...

  5. (转)游戏程序员养成计划 (更新2010.11.6)

    游戏程序员养成计划 (更新2010.11.6) 原文地址:http://www.cnblogs.com/clayman/archive/2009/05/17/1459001.html#2241553 ...

  6. 2021腾讯犀牛鸟校园布道师养成计划丨百校同行

    千里之行,基于硅步:万里之船,成于罗盘.2021腾讯犀牛鸟云开发新生工程教育"百校同行"--「云开发校园布道师养成计划」 正式回归! 本次布道师养成计划为高校学生打造的高自由度学习 ...

  7. 【周记】腾讯犀牛鸟「云开发」校园技术布道师养成计划

    一个月前开始试着学习微信小程序 恰好腾讯举办了这个[腾讯犀牛鸟「云开发」校园技术布道师养成计划]https://www.bilibili.com/read/cv4965254这个活动 技术增长 抛开活 ...

  8. 获奖结果公布|2020腾讯犀牛鸟云开发校园技术布道师养成计划

    导语: 为顺应信息技术行业发展趋势及人才需求,促进新时代云计算领域人才培养,在信息技术新工科产学研联盟的指导下,由腾讯云.腾讯高校合作和图灵教育联合主办,牛客网协办的2020腾讯犀牛鸟云开发校园技术布 ...

  9. Linux达人养成计划I详细笔记(二)Linux分区与安装

    本系列博文是听了课程Linux达人养成计划后的个人学习笔记,较为详细,供大家参考. 目录 第2章 Linux分区与安装 2.1系统分区 2.2 Linux安装 第2章 Linux分区与安装 2.1系统 ...

最新文章

  1. 051_InfiniteScroll无限滚动
  2. GDCM:gdcm::ImageFragmentSplitter的测试程序
  3. HDU 1028 Ignatius and the Princess III
  4. html5 can,基于html5 can-vas实现漫天飞雪效果实例
  5. 中国恒大、恒大物业在香港暂停交易
  6. Scala报错:error: overloaded method value logInfo with alternatives
  7. OCR文字识别技术总结(二)
  8. 读写分离设计:复制延迟?其实是你用错了
  9. python 转成摩尔斯电码_【无线电史话】比莫尔斯电码更直观 | 1919年的护林员通过Myer码传递信息...
  10. 【数据结构系列】严蔚敏C语言版算法实现并附带详细注释(逐步更新)
  11. 【NeatUpload】因用了NeatUpload大文件上传控件而导致Nonfile portion 4194304 bytes错误的解决方法
  12. 发那科服务器显示021,发那科(FANUC)系统报警代码大全
  13. Golang优化之内存对齐
  14. 《薄世宁医学通识讲义》笔记
  15. 什么是噪声,白噪声,加性噪声,乘性噪声
  16. 2021-09-23 latex 实心圆编号
  17. 多线程 ForkJoinPool
  18. [Excel]sumif函数对满足条件的单元格求和
  19. 北理工计算机组成原理在线作业,[北京师范大学]20秋《计算机组成原理》离线作业...
  20. LATEX使用 图文混排,文字环绕插图

热门文章

  1. 我的CSDN两周年小结
  2. Windows 10使用WSL部署Chatgpt_academic
  3. 响应式个人导航主页源码
  4. 利用树莓派制作智能音箱
  5. Elisp之实现代码自动高亮并跳转(十八)
  6. 实验一:验证MD5校验及MD5的性质
  7. 用java写一个表白神器,要有动画效果
  8. 统计学基础--数据基础
  9. python杭州培训达内
  10. 中国液态金属量子计算机,中国研究液态金属机器人已有十几年 领先他国