【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】神牛的养成计划的更多相关文章
- [BZOJ4212]神牛的养成计划
		[BZOJ4212]神牛的养成计划 试题描述 Hzwer 成功培育出神牛细胞,可最终培育出的生物体却让他大失所望...... 后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变,原先决定神 ... 
- BZOJ4212 神牛的养成计划 (字典树,bitset)
		题面 Description Hzwer成功培育出神牛细胞,可最终培育出的生物体却让他大失所望- 后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变,原先决定神牛特征的基因序列都被破坏了, ... 
- 【BZOJ4212】神牛的养成计划 Trie树+可持久化Trie树
		[BZOJ4212]神牛的养成计划 Description Hzwer成功培育出神牛细胞,可最终培育出的生物体却让他大失所望...... 后来,他从某同校女神 牛处知道,原来他培育的细胞发生了基因突变 ... 
- 【BZOJ-4212】神牛的养成计划       Trie树 + 可持久化Trie树
		4212: 神牛的养成计划 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 136 Solved: 27[Submit][Status][Discus ... 
- BZOJ 4212: 神牛的养成计划
		4212: 神牛的养成计划 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 142 Solved: 30[Submit][Status][Discus ... 
- 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 ... 
- Web前端开发工程师养成计划【转载】
		Web前端开发工程师养成计划(入门篇) 最原始的忠告:这个世界上有想法的人很多,但是有想法又能实现它的人太少! 首先要感谢伟大的Web2.0概念.产品概念.用户体验概念.jQuery插件,是它们在中国 ... 
- 高手养成计划基础篇-Linux第二季
		高手养成计划基础篇-Linux第二季 本文来源:i春秋社区-分享你的技术,为安全加点温度 前言 前面我们学习了文件处理命令和文件搜索命令,简单的了解了一下Linux,但是仅仅了解这样还不行,遇 ... 
随机推荐
- 180725-InfluxDB-v1.6.0安装和简单使用小结
			InfluxDB安装和简单使用小结 InfluxDB是一个时序性数据库,因为工作需求,安装后使用测试下是否支持大数据下的业务场景 说明: 安装最新版本 v1.6.0 集群版本要收费,单机版本免费 内部 ... 
- Git生成SSH密钥
			git config --global user.name "yangjianliang"配置用户名 git config --global user.email "52 ... 
- 用gdb调试程序(Linux环境)
			一般来说,GDB主要帮忙你完成下面四个方面的功能: 1.启动你的程序,可以按照你的自定义的要求随心所欲的运行程序. 2.可让被调试的程序在你所指定的调置的断点处停住.(断点可以是条件表达式) ... 
- 3.0 zookeeper的集群介绍、搭建、环境、安装
			zookeeper是本身是一种分布式协调服务(英文意思动物园园长因为Hadoop就是一个动物园,storm.hadoop.kafkaka.hbaser都是基于zookeeper开发的) 原理:Zook ... 
- File Transfer(并查集)
			题目大意:将多个电脑通过网线连接起来,不断查询2台电脑之间是否连通. 问题来源:中国大学mooc 05-树8 File Transfer (25 分) We have a network of com ... 
- Ubuntu系统下在PyCharm里用virtualenv集成TensorFlow
			我的系统环境 Ubuntu 18.04 Python3.6 PyCharm 2018.3.2 community(免费版) Java 1.8 安装前准备 由于众所周知的原因,安装中需要下载大量包,尽量 ... 
- Java线上应用故障排查之一:高CPU占用 (转)
			一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环. (友情提示:本博文章欢迎转载,但请注明出处:hankchen,http://www.blogjava.net/hank ... 
- 7. B+树
			一.B+树是应文件系统所需而产生的一种B树的变形树 1. 定义(使用阶数m来定义) 除了根结点外,其他非终端结点最多有m个关键字,最少有⌈m/2⌉个关键字 结点中的每个关键字对应一个子树 所有的非终端 ... 
- Scrum立会报告+燃尽图(十月十九日总第十次):
			此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2246 项目地址:https://git.coding.net/zhang ... 
- PSP DAILY软件功能说明书
			PSP DAILY软件功能说明书 一.开发背景 你在完成了一周的软件工程作业后,需要提交一个PSP图表,里面有4项,如下所示: 1.本周PSP表格,包含每项任务的开始.中断.结束.最终时间,格式如下: ... 
