BZOJ 4212: 神牛的养成计划
4212: 神牛的养成计划
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 142 Solved: 30
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
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
7
3
5
5
1
3
5
10
4
HINT
Source
万古神牛黄学长 Orz
又是一道可持久化Trie好题。
先想暴力,每次先找出有所能匹配上前缀的串,然后在看看这些串里有多少个还能匹配上后缀,这些串的个数就是最终答案。
然后发现,每次靠前缀筛出来的所有串一定具有一段相同的前缀,这个有点像后缀数组的那种感觉,就是先对所有串按照前缀排序,不难看出每次找出的前缀合法的串一定排成一个区间,我们想访问这个区间的所有串的逆序Trie,这个就是可持久化Trie树了。
从DaD3zZ那里看到这道题的,他说感觉对串按照前缀排序时使用了C++的Sort函数,逐位比较两个串的大小貌似比较暴力;但是不难想到,我们先建出正序的Trie后,在Trie上按顺序(a->z)DFS出来的就是按前缀排好序的了,这样复杂度就是完美的$O(\sum{Length})$,轻松过掉2000000。貌似出题人比较友好(可能就是比较懒),出的数据有点水……
代码没有,懒得写了…… 懒癌晚期
UPDATE 写了一发代码,然后图省事用的string,然后cin就给RE了,下午发现问题改成scanf就可以了。
#include <bits/stdc++.h> using namespace std; const int mxn = ;
const int mxm = ; inline void scan(string &s)
{
s.clear(); static char buf[mxm]; scanf("%s", buf); for (char *c = buf; *c; ++c)
s.push_back(*c);
} int n, m; int ord[mxn]; string str[mxn]; int end[mxm];
int son[mxm][]; int mini[mxm];
int maxi[mxm]; inline void insert(string &s, int id) {
static int tot = ; int p = , len = s.length(); for (int i = ; i < len; ++i) {
if (son[p][s[i] - 'a'] == )
son[p][s[i] - 'a'] = ++tot; p = son[p][s[i] - 'a'];
} end[p] = id;
} void getOrder(int p) {
static int cnt; mini[p] = cnt; if (end[p])
ord[++cnt] = end[p]; for (int i = ; i < ; ++i)
if (son[p][i])getOrder(son[p][i]); maxi[p] = cnt;
} int root[mxn]; int sum[mxm];
int nxt[mxm][]; void insert(int &t, int p, string &s, int d) {
static int tot = ; t = ++tot; sum[t] = sum[p] + ; memcpy(nxt[t], nxt[p], sizeof(nxt[t])); if (d < s.length())
insert(nxt[t][s[d] - 'a'], nxt[p][s[d] - 'a'], s, d + );
} inline void trie1(string &s, int <, int &rt, int ans) {
int p = , len = s.length(); for (int i = ; i < len; ++i)
s[i] = (s[i] - 'a' + ans) % + 'a'; lt = rt = ; for (int i = ; i < len; ++i)
p = son[p][s[i] - 'a']; lt = mini[p];
rt = maxi[p];
} inline void trie2(string &s, int lt, int rt, int &ans) {
int len = s.length(); reverse(s.begin(), s.end()); for (int i = ; i < len; ++i)
s[i] = (s[i] - 'a' + ans) % + 'a'; int a = root[lt], b = root[rt]; for (int i = ; i < len; ++i) {
a = nxt[a][s[i] - 'a'];
b = nxt[b][s[i] - 'a'];
} ans = sum[b] - sum[a];
} signed main(void) {
#ifndef ONLINE_JUDGE
freopen("in", "r", stdin);
freopen("out", "w", stdout);
#endif scanf("%d", &n); for (int i = ; i <= n; ++i)
scan(str[i]); for (int i = ; i <= n; ++i)
insert(str[i], i); getOrder(); for (int i = ; i <= n; ++i)
reverse(str[i].begin(), str[i].end()); for (int i = ; i <= n; ++i)
insert(root[i], root[i - ], str[ord[i]], ); scanf("%d", &m); for (int i = , lt, rt, ans = ; i <= m; ++i) {
static string s1, s2; scan(s1);
scan(s2); trie1(s1, lt, rt, ans);
trie2(s2, lt, rt, ans); printf("%d\n", ans);
}
}
@Author: YouSiki
BZOJ 4212: 神牛的养成计划的更多相关文章
- BZOJ.4212.神牛的养成计划(Trie 可持久化Trie)
BZOJ 为啥hzw的题也是权限题啊 考虑能够匹配\(s1\)这一前缀的串有哪些性质.对所有串排序,能发现可以匹配\(s1\)的是一段区间,可以建一棵\(Trie\)求出来,设为\([l,r]\). ...
- BZOJ 4212: 神牛的养成计划 可持久化trie+trie
思路倒是不难,但是这题卡常啊 ~ code: #include <bits/stdc++.h> #define N 2000004 #define M 1000005 #define SI ...
- 【BZOJ-4212】神牛的养成计划 Trie树 + 可持久化Trie树
4212: 神牛的养成计划 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 136 Solved: 27[Submit][Status][Discus ...
- [BZOJ4212]神牛的养成计划
[BZOJ4212]神牛的养成计划 试题描述 Hzwer 成功培育出神牛细胞,可最终培育出的生物体却让他大失所望...... 后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变,原先决定神 ...
- 【BZOJ4212】神牛的养成计划 Trie树+可持久化Trie树
[BZOJ4212]神牛的养成计划 Description Hzwer成功培育出神牛细胞,可最终培育出的生物体却让他大失所望...... 后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变 ...
- BZOJ4212 神牛的养成计划 (字典树,bitset)
题面 Description Hzwer成功培育出神牛细胞,可最终培育出的生物体却让他大失所望- 后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变,原先决定神牛特征的基因序列都被破坏了, ...
- BZOJ第1页养成计划
嗯,用这篇博客当一个目录,方便自己和学弟(妹?)们查阅.不定期更新. BZOJ1000 BZOJ1001 BZOJ1002 BZOJ1003 BZOJ1004 BZOJ1005 ...
- BZOJ第7页养成计划
嗯,用这篇博客当一个目录,方便自己和学弟(妹?)们查阅.不定期更新. BZOJ1600 BZOJ1601 BZOJ1602 BZOJ1603 BZOJ1604 BZOJ1605 ...
- 【bzoj4212】神牛的养成计划
Portal --> bzoj4212 Description 给你\(n\)个字符串,接下来有\(m\)个询问,每个询问由两个给定的字符串\(s_1\)和\(s_2\)组成,对于每个询问输 ...
随机推荐
- ASP.NET RAZOR自动生成的js Timer
<input type="hidden" value="@(Model.TimeLength)" id="examTimeLength" ...
- python语言程序设计5
1, 评估函数eval() 去掉参数最外侧引号并执行余下语句的函数. 比如eval("1"),经过运行可以得到数字 1 去得是单双引号,不是括号哦.. 广泛来说,能将任何字符串的形 ...
- C#使用FFMPEG推流,并且获取流保存在本地,随时取媒体进行播放!
最近开发了基于C#的推流器一直不大理想,终于在不懈努力之后研究了一点成果,这边做个笔记:本文着重在于讲解下如何使用ffmpeg进行简单的推流,看似简单几行代码没有官方的文档很吃力.并获取流的源代码:如 ...
- NodeMCU学习(二) : 如何使用NodeMCU进行开发
NodeMCU的GPIO口 Arduino的引脚号与NodeMCU的GPIO口直接对应,NodeMCU的GPIO函数pinMode, digitalWrite, DigitalRead也是和Ardu ...
- 基于 CentOS 搭建 FTP 文件服务
https://www.linuxidc.com/Linux/2017-11/148518.htm
- C#【结对编程作业】小学数学习题助手
一.软件成品展示 软件本体下载(包括程序及其更新日志,源码工程包,UML图,API接口文档,算法介绍文档,算式计算excel实例,浅查重程序) 链接: http://pan.baidu.com/s/1 ...
- 团队作业M1反思
经过这两个多月以来的软件工程的学习,还有团队项目的经历,总结反思如下: 首先,一个月的软件工程团队项目的进行让我对软件开发有了比较实际的认识,以前我们的编程多是个人编程,两人编程,程序难度低,代码量少 ...
- Python学习笔记 -- 第四章
高阶函数 变量可以指向函数 f=abs f(-10) 10 变量f指向abs函数,直接调用abs()函数和调用f()完全相同 传入参数 变量可以指向函数,函数的参数可以接收另一个函数的参数,这种函数成 ...
- PAT 1013 数素数
https://pintia.cn/problem-sets/994805260223102976/problems/994805309963354112 令P~i~表示第i个素数.现任给两个正整数M ...
- HDU 2096 小明A+B
http://acm.hdu.edu.cn/showproblem.php?pid=2096 Problem Description 小明今年3岁了, 现在他已经能够认识100以内的非负整数, 并且能 ...