4212: 神牛的养成计划

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 142  Solved: 30
[Submit][Status][Discuss]

Description

Hzwer成功培育出神牛细胞,可最终培育出的生物体却让他大失所望......
后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变,原先决定神牛特征的基因序列都被破坏了,神牛hzwer很生气,但他知道基因突变的低频性,说不定还有以下优秀基因没有突变,那么他就可以用限制性核酸内切酶把它们切出来,然后再构建基因表达载体什么的,后面你懂的......
黄学长现在知道了N个细胞的DNA序列,它们是若干个由小写字母组成的字符串。一个优秀的基因是两个字符串s1和s2,当且仅当s1是某序列的前缀的同时,s2是这个序列的后缀时,hzwer认为这个序列拥有这个优秀基因。
现在黄学长知道了M个优秀基因s1和s2,它们想知道对于给定的优秀基因,有多少个细胞的DNA序列拥有它。

Input

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

Output

输出M行,每行一个数,第i行的数表示有多少个序列拥有第i个优秀基因。

Sample Input

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

Sample Output

4
7
3
5
5
1
3
5
10
4

HINT

N<=2000
L1<=2000000
M<=100000
L2<=2000000

Source

[Submit][Status][Discuss]

万古神牛黄学长 Orz

又是一道可持久化Trie好题。

先想暴力,每次先找出有所能匹配上前缀的串,然后在看看这些串里有多少个还能匹配上后缀,这些串的个数就是最终答案。

然后发现,每次靠前缀筛出来的所有串一定具有一段相同的前缀,这个有点像后缀数组的那种感觉,就是先对所有串按照前缀排序,不难看出每次找出的前缀合法的串一定排成一个区间,我们想访问这个区间的所有串的逆序Trie,这个就是可持久化Trie树了。

从DaD3zZ那里看到这道题的,他说感觉对串按照前缀排序时使用了C++的Sort函数,逐位比较两个串的大小貌似比较暴力;但是不难想到,我们先建出正序的Trie后,在Trie上按顺序(a->z)DFS出来的就是按前缀排好序的了,这样复杂度就是完美的$O(\sum{Length})$,轻松过掉2000000。貌似出题人比较友好(可能就是比较懒),出的数据有点水……

代码没有,懒得写了…… 懒癌晚期

UPDATE 写了一发代码,然后图省事用的string,然后cin就给RE了,下午发现问题改成scanf就可以了。

  1 #include <bits/stdc++.h>
  2
  3 using namespace std;
  4
  5 const int mxn = 2005;
  6 const int mxm = 2100005;
  7
  8 inline void scan(string &s)
  9 {
 10     s.clear();
 11
 12     static char buf[mxm];
 13
 14     scanf("%s", buf);
 15
 16     for (char *c = buf; *c; ++c)
 17         s.push_back(*c);
 18 }
 19
 20 int n, m;
 21
 22 int ord[mxn];
 23
 24 string str[mxn];
 25
 26 int end[mxm];
 27 int son[mxm][26];
 28
 29 int mini[mxm];
 30 int maxi[mxm];
 31
 32 inline void insert(string &s, int id) {
 33     static int tot = 1;
 34
 35     int p = 1, len = s.length();
 36
 37     for (int i = 0; i < len; ++i) {
 38         if (son[p][s[i] - 'a'] == 0)
 39             son[p][s[i] - 'a'] = ++tot;
 40
 41         p = son[p][s[i] - 'a'];
 42     }
 43
 44     end[p] = id;
 45 }
 46
 47 void getOrder(int p) {
 48     static int cnt;
 49
 50     mini[p] = cnt;
 51
 52     if (end[p])
 53         ord[++cnt] = end[p];
 54
 55     for (int i = 0; i < 26; ++i)
 56         if (son[p][i])getOrder(son[p][i]);
 57
 58     maxi[p] = cnt;
 59 }
 60
 61 int root[mxn];
 62
 63 int sum[mxm];
 64 int nxt[mxm][26];
 65
 66 void insert(int &t, int p, string &s, int d) {
 67     static int tot = 1;
 68
 69     t = ++tot;
 70
 71     sum[t] = sum[p] + 1;
 72
 73     memcpy(nxt[t], nxt[p], sizeof(nxt[t]));
 74
 75     if (d < s.length())
 76         insert(nxt[t][s[d] - 'a'], nxt[p][s[d] - 'a'], s, d + 1);
 77 }
 78
 79 inline void trie1(string &s, int &lt, int &rt, int ans) {
 80     int p = 1, len = s.length();
 81
 82     for (int i = 0; i < len; ++i)
 83         s[i] = (s[i] - 'a' + ans) % 26 + 'a';
 84
 85     lt = rt = 0;
 86
 87     for (int i = 0; i < len; ++i)
 88         p = son[p][s[i] - 'a'];
 89
 90     lt = mini[p];
 91     rt = maxi[p];
 92 }
 93
 94 inline void trie2(string &s, int lt, int rt, int &ans) {
 95     int len = s.length();
 96
 97     reverse(s.begin(), s.end());
 98
 99     for (int i = 0; i < len; ++i)
100         s[i] = (s[i] - 'a' + ans) % 26 + 'a';
101
102     int a = root[lt], b = root[rt];
103
104     for (int i = 0; i < len; ++i) {
105         a = nxt[a][s[i] - 'a'];
106         b = nxt[b][s[i] - 'a'];
107     }
108
109     ans = sum[b] - sum[a];
110 }
111
112 signed main(void) {
113 #ifndef ONLINE_JUDGE
114     freopen("in", "r", stdin);
115     freopen("out", "w", stdout);
116 #endif
117
118     scanf("%d", &n);
119
120     for (int i = 1; i <= n; ++i)
121         scan(str[i]);
122
123     for (int i = 1; i <= n; ++i)
124         insert(str[i], i);
125
126     getOrder(1);
127
128     for (int i = 1; i <= n; ++i)
129         reverse(str[i].begin(), str[i].end());
130
131     for (int i = 1; i <= n; ++i)
132         insert(root[i], root[i - 1], str[ord[i]], 0);
133
134     scanf("%d", &m);
135
136     for (int i = 1, lt, rt, ans = 0; i <= m; ++i) {
137         static string s1, s2;
138
139         scan(s1);
140         scan(s2);
141
142         trie1(s1, lt, rt, ans);
143         trie2(s2, lt, rt, ans);
144
145         printf("%d\n", ans);
146     }
147 }

@Author: YouSiki

转载于:https://www.cnblogs.com/yousiki/p/6550484.html

BZOJ 4212: 神牛的养成计划相关推荐

  1. 4212: 神牛的养成计划

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

  2. [BZOJ4212]神牛的养成计划

    [BZOJ4212]神牛的养成计划 试题描述 Hzwer 成功培育出神牛细胞,可最终培育出的生物体却让他大失所望...... 后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变,原先决定神 ...

  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. 06-老马jQuery教程-jQuery高级
  2. Linux jupyter安装位置,Linux下安装jupyter
  3. tkinter menu
  4. CentOS命令行安装配置KVM详细教程
  5. stm32--FatFs调试过程(SPIFlash)
  6. react —— diff算法与VDOM
  7. 在Word2019中不能插入公式的解决办法
  8. R矩形树状图 treemap
  9. win10专业版与家庭版区别分析
  10. vendor分区的库无法调用system分区的库
  11. App逆向 Frida - 夜神模拟器安装配置 基本使用
  12. 苹果主题商店_小米怕被苹果找茬,开始下架相关IOS主题了!
  13. TT语音:游戏社交乱象难平
  14. python html5 便利店收银系统_python面向过程编程小程序- 模拟超市收银系统
  15. 马克斯-普朗克计算机科学研究所,GAMES Webinar 2018-38期 | 陈仁杰(德国马克斯普朗克计算机研究所)...
  16. 学会继承、多态、封装(1)——Java实现宠物店(领养宠物)
  17. 计算机技术专业 英文,计算机技术与应用专业英文简历模板
  18. 网页怎么做成二维码?如何扫码查看网页链接?
  19. Java Swing编写udp数据传输的聊天程序demo
  20. windows10 长时间休眠后黑屏解决办法

热门文章

  1. Mysql学习总结(14)——Mysql主从复制配置
  2. mysql二级制包安装 for RedHat Linux Enterprise6.4
  3. MATLAB获取一个目录中的所有文件
  4. 4、Python —— 函数
  5. java程序员求职计划_2017年java程序员面试经验(500字)
  6. php读取 rss pubdate,PHP产生RSS pubDate所需日期时间格式的方法
  7. python isinstance函数判断object的类型
  8. Python 3下Matplotlib画图中文显示乱码的解决方法
  9. tomcat上传war包失败
  10. CI类实现session基本用法