HDU - 6096 处理后缀的字典树
题意:给定n个字符串,m次询问,每次询问多少个字符串前缀是pre且后缀是suf,前后缀不可相交
字典树同时存储前后缀,假设字符串长为len则更新2*len个节点,依次按s[0],s[len-1],s[1],s[len-2],s[2]...更新
对于询问,按pre[0],suf[len2-1],pre[1],suf[len2-2],...pre[len1-1],suf[0]查询
如果前后缀不等长则用特殊字符填充,询问若碰到特殊字符就当前层暴搜(由于后一层前后缀肯定存在确定字符,所以不会被卡)
必须要确保的是询问时字典树中任一字符串必须长度大于等于当前查询的前后缀长度和(xxx xx xx非法)
因此需要离线处理
时间复杂度\(O(能过)\)
#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define println(a) printf("%lld\n",(ll)a)
using namespace std;
const int MAXN = 2e5 + 11;
const int MOD = 1e9+7;
typedef long long ll;
const ll INF = 1ll<<62;
ll read(){
ll x = 0, f = 1; register char ch = getchar();
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x*f;
}
string str[MAXN];
bool cmp(const string &a,const string &b){
return a.length()<b.length();
}
struct Q{
string pre,suf;
int id,len;
Q(){};
Q(string a,string b,int _id){
pre=a;
suf=b;
id=_id;
len=pre.length();
len+=suf.length();
if(pre.length()<suf.length()){
for(int i=pre.length();i<suf.length();i++){
pre.push_back('@');
}
}else if(suf.length()<pre.length()){
string t((int)pre.length()-suf.length(),'@');
suf=t+suf;
}
}
bool operator < (const Q &QAQ) const{
return len<QAQ.len;
}
}q[MAXN];
int ans[MAXN];
const int MAXV = 3e6+11;
struct Trie{
int son[MAXV][26];
int size[MAXV];
int tot,root;
void init(){
root=tot=1;
size[root]=0;
rep(i,0,25) son[root][i]=0;
}
int node(){
++tot;
size[tot]=0;
rep(i,0,25) son[tot][i]=0;
return tot;
}
void insert(const string &str){
int o=root,t;
int cur1=0,cur2=str.length();
int len=2*str.length();
for(int i=0;i<len;i++){
if(i&1) t=--cur2;
else t=cur1++;
size[o]++;
int wh=str[t]-'a';
if(son[o][wh]==0) son[o][wh]=node();
o=son[o][wh];
}
size[o]++;
}
int ans;
void query(int o,int dep,const string &s){
if(o==0) return;
if(dep==s.length()){
ans+=size[o];
return;
}
if(s[dep]=='#'||s[dep]=='@'){
for(int j=0;j<26;j++) query(son[o][j],dep+1,s);
}else{
query(son[o][s[dep]-'a'],dep+1,s);
}
}
}trie;
int main(){
ios::sync_with_stdio(false);
int T; cin>>T;
while(T--){
int n,m;
cin>>n>>m;
rep(i,1,n) cin>>str[i];
sort(str+1,str+1+n,cmp);
string a,b;
rep(i,1,m){
cin>>a>>b;
q[i]=Q(a,b,i);
}
sort(q+1,q+1+m);
trie.init();
int cur=n;
string s;
rrep(i,m,1){
while(cur>0&&str[cur].length()>=q[i].len){
trie.insert(str[cur]);
cur--;
}
s.clear();
int len=2*q[i].pre.length();
int cur1=0,cur2=len>>1;
for(int j=0;j<len;j++){
char ch;
if(j&1) ch=q[i].suf[--cur2];
else ch=q[i].pre[cur1++];
s.push_back(ch);
}
trie.ans=0; trie.query(1,0,s);
ans[q[i].id]=trie.ans;
}
rep(i,1,m){
cout<<ans[i]<<endl;
}
}
return 0;
}
HDU - 6096 处理后缀的字典树的更多相关文章
- HDU 4287 Intelligent IME(字典树数组版)
Intelligent IME Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 4757 Tree 可持久化字典树
Tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4757 Des ...
- hdu 4099 Revenge of Fibonacci 字典树+大数
将斐波那契的前100000个,每个的前40位都插入到字典树里(其他位数删掉),然后直接查询字典树就行. 此题坑点在于 1.字典树的深度不能太大,事实上,超过40在hdu就会MLE…… 2.若大数加法时 ...
- HDU 1247 - Hat’s Words - [字典树水题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1247 Problem DescriptionA hat’s word is a word in the ...
- HDU 1251 统计难题(字典树模板题)
http://acm.hdu.edu.cn/showproblem.php?pid=1251 题意:给出一些单词,然后有多次询问,每次输出以该单词为前缀的单词的数量. 思路: 字典树入门题. #inc ...
- HDU 1251 统计难题(字典树 裸题 链表做法)
Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己 ...
- TOJ3097: 单词后缀 (字典树 or map瞎搞)
传送门 (<---可以点击的~) 时间限制(普通/Java):1000MS/3000MS 内存限制:65536KByte 描述 有些英语单词后缀都是一样的,现在我们需要从给定的一堆单词里 ...
- hdu 1251 统计难题(字典树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251 统计难题 Time Limit: 4000/2000 MS (Java/Others) M ...
- HDU 5715 XOR 游戏 二分+字典树
XOR 游戏 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5715 Description 众所周知,度度熊喜欢XOR运算(XOR百科). 今天,它 ...
随机推荐
- docker+zookeeper+mesos+marathon集群
实验环境: 主机名 ip地址 运行服务 安装组件 docker-master1 192.168.20.210 zookeepermesos-mastermarathon mesosmarathonme ...
- ASP.NET Web API之消息[拦截]处理(转)
出处:http://www.cnblogs.com/Leo_wl/p/3238719.html 标题相当难取,内容也许和您想的不一样,而且网上已经有很多这方面的资料了,我不过是在实践过程中作下记录.废 ...
- CoreDNS for kubernetes Service Discovery
一.CoreDNS简介 Kubernetes包括用于服务发现的DNS服务器Kube-DNS. 该DNS服务器利用SkyDNS的库来为Kubernetes pod和服务提供DNS请求.SkyDNS2的作 ...
- JQuery中button提交表单报TypeError: elem[type] is not a function jquery
错误: TypeError: elem[type] is not a function jquery 解决: 出现这种现象的原因是,提交的表单中,有标签的name,有以submit命名的 name中不 ...
- mongodb-win32-i386-3.0.6 使用常见错误
1.Error parsing YAML config file: yaml-cpp: error at line 3, column 28: unknown escape character: m ...
- awk基础01-基本用法
什么是awk awk 是一门解释型的编程语言,支持条件判断,数组.循环等功能.可用于文本处理.输出格式化的文本信息.执行数学运算.字符串等操作. awk在处理文件时按行进行逐行处理,即 ...
- 使用Git 管理heroku的项目(windows)
此过程与管理github中的项目类似,即是普通的git配置 安装 Heroku Toolbelt, 里面包含了 msygit Foreman,以及heroku的命令行界面 1.首先在heroku上新建 ...
- Fork/Join 型线程池与 Work-Stealing 算法
JDK 1.7 时,标准类库添加了 ForkJoinPool,作为对 Fork/Join 型线程池的实现.Fork 在英文中有 分叉 的意思,而 Join 有 合并 的意思.ForkJoinPool ...
- 快速排序(Quicksort)的Javascript实现(转载)
日本程序员norahiko,写了一个排序算法的动画演示,非常有趣. 这个周末,我就用它当做教材,好好学习了一下各种排序算法. 排序算法(Sorting algorithm)是计算机科学最古老.最基本的 ...
- SQLServer中数据加密方法
对SQLServer中的数据进行加密,有三种方法, 1. 在程序语言中先对数据进行加密后再把加密后的数据保存在SQLServer数据库中: 2. 利用SQLServer未公开的加密密码函数,在SQ ...