Portal --> bzoj4212

Description

​  给你\(n\)个字符串,接下来有\(m\)个询问,每个询问由两个给定的字符串\(s_1\)和\(s_2\)组成,对于每个询问输出\(n\)个字符串中有多少个同时满足\(s_1\)是其前缀且\(s_2\)是其后缀,强制在线

​​  数据范围:\(n<=2000,m<=100000\),\(n\)个字符串总长度以及询问字符串总长度均\(<=2000000\)

​  

Solution

​​  (怎么感觉自己好像没有学过trie一样是因为太久没有写所以根本没有往那个方向想吗==)

​  最暴力的做法的话。。想法很简单:先确定哪些字符串满足\(s_1\)是前缀,再看其中满足\(s_2\)是后缀的数量

​  前缀这种东西的话,如果说我们将\(n\)个字符串丢到trie里面,将dfs一遍之后各个字符串结尾对应节点的访问顺序存在一个数组里面,那么对于一个询问\((s_1,s_2)\),满足\(s_1\)是前缀的字符串的结尾对应节点必定在一个子树当中,反应到数组里面的话就是一个区间

​​  那所以接下来我们要做的就是查这个区间内的字符串有多少个满足\(s_2\)是后缀,只要将所有的串反转然后丢到trie里面,就又转成查前缀的问题了,解决方式和上面一样

​​  至于区间这个问题,直接可持久化一下就好了

​  

​  mark:**没事还是不要随便用getline好了==评测的时候超级容易翻车 **

​​  mark:前缀什么的也是应该考虑一下trie啊qwq不要看到字符串什么的就满脑子sa、sam之类的

​  

​  代码大概长这个样子

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define mp make_pair
#define Pr pair<int,int>
using namespace std;
const int N=2010,L=2000010,C=26;
string s[N],s1,s2;
char tmps[L];
int st[N],lis[N];
int n,tot,lastans,m;
namespace T1{/*{{{*/
const int N=::L;
int ch[N][C],st[N],ed[N];
vector<int> mark[N];
int tot,rt;
void init(){rt=1;tot=1;}
void insert(string s,int id){
int len=s.length(),now=rt,c;
for (int i=0;i<len;++i){
c=s[i]-'a';
if (!ch[now][c]) ch[now][c]=++tot;
now=ch[now][c];
}
mark[now].push_back(id);
}
void dfs(int x){
bool have=mark[x].size();
if (mark[x].size()){
st[x]=lis[0]+1;
for (int i=0;i<mark[x].size();++i)
lis[++lis[0]]=mark[x][i];
}
bool flag=false;
for (int i=0;i<C;++i){
if (!ch[x][i]) continue;
dfs(ch[x][i]);
if (!flag&&!have)
st[x]=st[ch[x][i]];
flag=true;
}
ed[x]=lis[0];
}
void get_order(){lis[0]=0; dfs(rt);}
Pr query(string s){
int now=rt,len=s.length(),c;
for (int i=0;i<len;++i){
//printf("%c\n",s[i]);
c=(s[i]-'a'+lastans)%C;
now=ch[now][c];
}
if (!now) return mp(-1,-1);
return mp(st[now],ed[now]);
}
}/*}}}*/
namespace T2{/*{{{*/
const int N=::L;
int ch[N][C],rt[::N],cnt[N];
int tot;
void init(){tot=0;rt[0]=0;}
int newnode(int pre){
cnt[++tot]=cnt[pre];
for (int i=0;i<C;++i) ch[tot][i]=ch[pre][i];
return tot;
}
void _insert(int pre,int &x,string &s,int loc){
x=newnode(pre);
++cnt[x];
if (loc<0) return;
int c=(s[loc]-'a'+lastans)%C;
_insert(ch[pre][c],ch[x][c],s,loc-1);
}
void insert(int pre,int x,string &s){_insert(rt[pre],rt[x],s,s.length()-1);}
int query(int l,int r,string s){
int nowl=rt[l],nowr=rt[r],c,len=s.length();
int ret=0;
for (int i=len-1;i>=0&&(nowl||nowr);--i){
c=(s[i]-'a'+lastans)%C;
nowl=ch[nowl][c];
nowr=ch[nowr][c];
}
return cnt[nowr]-cnt[nowl];
}
}/*}}}*/
void print(string s){
int len=s.length();
for (int i=0;i<len;++i) printf("%c",s[i]);
printf("\n");
}
void get_s(string &s){
scanf("%s",tmps);
int len=strlen(tmps);
s.resize(0);
for (int i=0;i<len;++i)
s.push_back(tmps[i]);
} int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
char ch;
Pr rec;
scanf("%d\n",&n);
T1::init(); T2::init();
lastans=0;
for (int i=1;i<=n;++i){
get_s(s[i]);
//print(s[i]);
T1::insert(s[i],i);
}
T1::get_order();
for (int i=1;i<=lis[0];++i){
T2::insert(i-1,i,s[lis[i]]);
}
scanf("%d\n",&m);
for (int i=1;i<=m;++i){
get_s(s1);
get_s(s2);
//print(s1);print(s2);
rec=T1::query(s1);
if (rec.first!=-1)
lastans=T2::query(rec.first-1,rec.second,s2);
else lastans=0;
printf("%d\n",lastans);
}
}

【bzoj4212】神牛的养成计划的更多相关文章

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

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

  2. BZOJ4212 神牛的养成计划 (字典树,bitset)

    题面 Description Hzwer成功培育出神牛细胞,可最终培育出的生物体却让他大失所望- 后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变,原先决定神牛特征的基因序列都被破坏了, ...

  3. 【BZOJ4212】神牛的养成计划 Trie树+可持久化Trie树

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

  4. 【BZOJ-4212】神牛的养成计划 Trie树 + 可持久化Trie树

    4212: 神牛的养成计划 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 136  Solved: 27[Submit][Status][Discus ...

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

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

  6. BZOJ.4212.神牛的养成计划(Trie 可持久化Trie)

    BZOJ 为啥hzw的题也是权限题啊 考虑能够匹配\(s1\)这一前缀的串有哪些性质.对所有串排序,能发现可以匹配\(s1\)的是一段区间,可以建一棵\(Trie\)求出来,设为\([l,r]\). ...

  7. BZOJ 4212: 神牛的养成计划 可持久化trie+trie

    思路倒是不难,但是这题卡常啊 ~ code: #include <bits/stdc++.h> #define N 2000004 #define M 1000005 #define SI ...

  8. Web前端开发工程师养成计划【转载】

    Web前端开发工程师养成计划(入门篇) 最原始的忠告:这个世界上有想法的人很多,但是有想法又能实现它的人太少! 首先要感谢伟大的Web2.0概念.产品概念.用户体验概念.jQuery插件,是它们在中国 ...

  9. 高手养成计划基础篇-Linux第二季

    高手养成计划基础篇-Linux第二季   本文来源:i春秋社区-分享你的技术,为安全加点温度   前言 前面我们学习了文件处理命令和文件搜索命令,简单的了解了一下Linux,但是仅仅了解这样还不行,遇 ...

随机推荐

  1. selenium自动化之定位多个元素

    前面我们讲的都是如何定位单个元素,下面讲下怎么去定位多个元素,并且输出文本. 以百度为例:获取标红的这一组元素的文本 这里我用到的是xpath来定位的://div[@id="u1" ...

  2. Appium+python 自动发送邮件(1)(转)

    (原文:https://www.cnblogs.com/fancy0158/p/10056091.html) SMTP:简单传输协议,实在Internet上传输Email的事实标准. Python的s ...

  3. JavaScript学习笔记(三)——对象

    第四章 理解对象 1 说明 对象的状态:属性,行为:方法: 对象定义放在花括号内: 用冒号分隔属性名和属性值: 用逗号分隔属性名和属性值对,包括方法: 最后一个属性值后面不加逗号: 属性名可以是任何字 ...

  4. 【ZABBIX】Zabbix触发器的告警原理及创建方法

    概述:       触发器中的表达式使用很灵活,我们可以创建一个复杂的逻辑测试监控,触发器表达式形式如下: {<server>:<key>.<function>(& ...

  5. Material Safety Data Sheet,MSDS - 化学品安全说明书

    化学品安全说明书(Material Safety Data Sheet)MSDS,国际上称作化学品安全信息卡,是化学品生产商和经销商按法律要求必须提供的化学品理化特性(如PH值,闪点,易燃度,反应活性 ...

  6. sparkSQL中RDD——DataFrame——DataSet的区别

    spark中RDD.DataFrame.DataSet都是spark的数据集合抽象,RDD针对的是一个个对象,但是DF与DS中针对的是一个个Row RDD 优点: 编译时类型安全 编译时就能检查出类型 ...

  7. loadrunner socket协议问题归纳(3)

    摘要:通过实例讲解loadrunner中的socket协议性能测试的一种测试方法,如何不依赖loadrunner既定规则,自行控制收发数据包 关键词:Loadrunner,socket,自行控制,收发 ...

  8. USACO 1.3.3 Calf Flac(Manacher算法)

    Description 据说如果你给无限只母牛和无限台巨型便携式电脑(有非常大的键盘),那么母牛们会制造出世上最棒的回文.你的工作就是去寻找这些牛制造的奇观(最棒的回文). 在寻找回文时不用理睬那些标 ...

  9. “Hello World!”团队第六周的第一次会议

    今天是我们团队“Hello World!”团队第六周召开的第一次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.Todo List 六.会议照片 七.燃尽图 一.会议时间 ...

  10. 《Linux内核与分析》第五周

    20135130王川东 一.给MenuOS增加time和time-asm命令 命令:1.强制删除:rm menu -rf 2.克隆:git clone (后跟需要克隆数据所在的位置) 3.自动编译,自 ...