hdu 6096 String
题
OvO http://acm.hdu.edu.cn/showproblem.php?pid=6096
( 2017 Multi-University Training Contest - Team 6 - 1001)
解
对于n个串,构造新串。(构造方法:例如若串为ABCDE,构造新串为AEBDCCDBEA)、
将新串插入到字典树(字典树每个节点存放一个vector)中,对于每个新串遍历到的节点,将原串的长度长度放入这些节点的vector中、
将字典树每个节点的vector从小到大排序。
对于询问的前后缀,类似地构造新串,空余出补*,(例如前缀ABC,后缀DEFGH,构造新串为AHBGCF*E*D)
然后对于这些新串在字典树中进行询问,对于每个匹配到的节点,合法串的数量就是vector中保存的长度大于等于前缀后缀长度和的数字的数量。
(思路来源于某大佬)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue> using namespace std; const int M=5e5+44;
const int N=1e5+44; struct Node
{
int len,pos;
}; queue<Node> que; struct Trie
{
const static int TRIE_M=1204000;
const static int CHAR_SIZE=26; int root,tol,ch[TRIE_M][27];
vector<int> tree[TRIE_M]; int newnode()
{
tree[tol].clear();
for(int i=0;i<26;i++)
ch[tol][i]=-1;
return tol++;
} void init()
{
tol=0;
root=newnode();
} void insert(char strtmp[],int lentmp)
{
// cout<<"strtmp: "<<strtmp<<endl;
int i,j;
int now=root,nxt,valtmp;
for(i=0;i<lentmp;i++)
{
valtmp=strtmp[i]-'a';
if(ch[now][valtmp]==-1)
ch[now][valtmp]=newnode();
now=ch[now][valtmp];
tree[now].push_back(lentmp/2);
// cout<<"now: "<<now<<" tree[now] size: "<<tree[now].size()<<endl;
}
} void build()
{
for(int i=0;i<tol;i++)
sort(tree[i].begin(),tree[i].end());
} int getval(int pos,int xlen)
{
int li=-1,ri=tree[pos].size(),mid;
// cout<<"getval pos:"<<pos<<' '<<" size: "<<tree[pos].size()<<endl;
// cout<<"detail val:"<<tree[pos][0]<<' '<<tree[pos][1]<<endl;
while(li<ri-1)
{
mid=(li+ri)>>1;
if(tree[pos][mid]<xlen)
li=mid;
else ri=mid;
}
// cout<<"li: "<<li<<endl;
return tree[pos].size()-(li+1);
} int query(char strtmp[],int lentmp,int xlen)
{
char chrtmp;
int i,j,ret=0,pos,nxt;
Node q,qq;
while(!que.empty())
que.pop();
q.len=0; q.pos=0;
que.push(q);
while(!que.empty())
{
q=que.front(); que.pop();
chrtmp=strtmp[q.len];
pos=q.pos;
// cout<<chrtmp<<' '<<pos;
// if(chrtmp!='*')
// cout<<" ch[pos][chrtmp-'a']= "<<ch[pos][chrtmp-'a'];
// cout<<endl;
if(chrtmp=='*')
for(i=0;i<26;i++)
{
nxt=ch[pos][i];
if(nxt!=-1)
{
qq.len=q.len+1;
qq.pos=nxt;
if(qq.len==lentmp)
ret+=getval(qq.pos,xlen);
else que.push(qq);
}
}
else
{
nxt=ch[pos][chrtmp-'a'];
if(nxt!=-1)
{
qq.len=q.len+1;
qq.pos=nxt;
if(qq.len==lentmp)
ret+=getval(qq.pos,xlen);
else que.push(qq);
}
}
}
return ret;
}
} trie; int n,q;
char strtmp[M],pretmp[M],suftmp[M],strget[M]; int main()
{
// freopen("数据\\1001.in","r",stdin);
// freopen("数据\\fxxl1001.out","w",stdout);
int lentmp,prelen,suflen;
int cas,i,j,ans;
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&n,&q);
trie.init();
for(i=1;i<=n;i++)
{
scanf("%s",strtmp);
lentmp=strlen(strtmp);
for(j=0;j<lentmp;j++)
{
strget[j*2]=strtmp[j];
strget[j*2+1]=strtmp[lentmp-1-j];
}
trie.insert(strget,lentmp*2);
}
trie.build();
for(i=1;i<=q;i++)
{
scanf("%s%s",pretmp,suftmp);
reverse(suftmp,suftmp+strlen(suftmp));
prelen=strlen(pretmp); suflen=strlen(suftmp);
lentmp=max(prelen,suflen);
for(j=0;j<lentmp;j++)
{
if(j<prelen)
strget[j*2]=pretmp[j];
else strget[j*2]='*';
if(j<suflen)
strget[j*2+1]=suftmp[j];
else strget[j*2+1]='*';
}
lentmp*=2;
if(strget[lentmp-1]=='*') lentmp--;
ans=trie.query(strget,lentmp,prelen+suflen);
printf("%d\n",ans);
}
}
return 0;
} /* 1
4 1
aaaa
aaaaa
aaaaa
aa
aa aa */
hdu 6096 String的更多相关文章
- 2017多校第6场 HDU 6096 String AC自动机
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6096 题意:给了一些模式串,然后再给出一些文本串的不想交的前后缀,问文本串在模式串的出现次数. 解法: ...
- HDU 6096 String(AC自动机+树状数组)
题意 给定 \(n\) 个单词,\(q\) 个询问,每个询问包含两个串 \(s_1,s_2\),询问有多少个单词以 \(s_1\) 为前缀, \(s_2\) 为后缀,前后缀不能重叠. \(1 \leq ...
- HDU 6096 String (AC自动机)
题目链接 Problem Description Bob has a dictionary with N words in it. Now there is a list of words in wh ...
- 2017ACM暑期多校联合训练 - Team 6 1001 HDU 6096 String (字符串处理 字典树)
题目链接 Problem Description Bob has a dictionary with N words in it. Now there is a list of words in wh ...
- HDU 6096 String (AC自动机)
题意:给出n个字符串和q个询问,每次询问给出两个串 p 和 s .要求统计所有字符串中前缀为 p 且后缀为 s (不可重叠)的字符串的数量. 析:真是觉得没有思路啊,看了官方题解,真是好复杂. 假设原 ...
- HDU 6096 String 排序 + 线段树 + 扫描线
String Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others) Problem De ...
- HDU 3374 String Problem (KMP+最大最小表示)
HDU 3374 String Problem (KMP+最大最小表示) String Problem Time Limit: 2000/1000 MS (Java/Others) Memory ...
- HDU - 6096 :String (AC自动机,已知前后缀,匹配单词,弱数据)
Bob has a dictionary with N words in it. Now there is a list of words in which the middle part of th ...
- HDU 3374 String Problem(KMP+最大/最小表示)
String Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
随机推荐
- [转帖]docker容器保持运行不退出
docker容器保持运行不退出 2019年01月20日 23:21:22 chvalrous 阅读数 1511 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...
- Oracle导入/导出某个用户下的数据库
导出 exp用户名/密码@数据库实例owner=用户名file=文件存储路径 例如:exp MM/123456@ORCL owner=MM file=F\abcd.dmp 导入 imp用户名/密码@数 ...
- PAT A1020 Tree Traversals(25)
题目描述 Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder ...
- centos7 使用nginx + tornado + supervisor搭建服务
如何在Linux下部署一个简单的基于Nginx+Tornado+Supervisor的Python web服务. Tornado:官方介绍,是使用Python编写出来的一个极轻量级.高可伸缩性和非阻塞 ...
- django channels
django channels django channels 是django支持websocket的一个模块. 1. 安装 `pip3 install channels` 2. 快速上手 2.1 在 ...
- HTML 标签的 for 属性
HTML 标签的 for 属性 for 属性规定 label 与哪个表单元素绑定. 隐式和显式的联系 label通常以下面两种方式中的一种来和表单控件相联系: 将表单控件作为标记标签的内容,这样的就是 ...
- js排列组合
/* 全排列主要用到的是递归和数组的插入 arr: 需要排列的数组 第一步:从里面取一个,创建一个新的数组,形式为二维,例如arr = [1,2,3]; 取出3(没有特殊要求,随便取一个),放入 te ...
- Aveva Marine 新建项目001
1# 项目代号定义,三个字符,例如Abc 2# 新建文件夹,命名为“Abc” 3# 新建文件名为evars.bat文件,放到项目文件夹的根目录 内容为: SET Abc000=项目文件夹路径\Abc0 ...
- shiro学习(三,shiro加密)
shiro加密 使用MD5加密 认证 //自定义的Realm 域 public class CustomRealmSecret extends AuthorizingRealm { @Overrid ...
- 深入探讨java的类加载器
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一.它使得 Java 类可以被动态加载到 Java 虚拟机中并执行.类加载器从 JDK 1.0 就出现了,最初是为了满足 Ja ...