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 ...
随机推荐
- 【Python】【基础知识】【内置常量】
Python的内置常量有: False.True.None.NotImplemented.Ellipsis.__debug__ 由 site 模块添加的常量:quit.exit.copyright.c ...
- SpreadJS V13.0发布,聚焦表单设计与数据交互,让您的工作效率突飞猛进!
纯前端表格控件SpreadJS,是一款成功应用于华为.招商银行.天弘基金.苏宁易购等国内外知名企业的前端开发工具,其带来的价值不仅体现在帮助开发人员在其Web应用程序中快速构建 Web Excel . ...
- 这可能是最简单易懂的 ZooKeeper 笔记
分布式架构 CAP 与 BASE 理论 一致性协议 初识 Zookeeper Zookeeper 介绍 Zookeeper 工作机制 Zookeeper 特点 Zookeeper 数据结构 Zooke ...
- SQL Server 2019 Linux Docker 在主机上以其他非根用户的身份运行容器
docker logs mssql2019SQL Server 2019 will run as non-root by default.This container is running as us ...
- HTML accessKey约定俗成的标准
accessKey属性提供了键盘快捷键 例: <a href="index.html" accessKey="1">Home</a> 这 ...
- django进阶版1
目录 字段中choice参数 MTV与MVC模型 AJAX(*********) Ajax普通请求 Ajax传json格式化数据 Ajax传文件 序列化组件 Ajax+sweetalert 字段中ch ...
- GTID复制
什么是GTID呢, 简而言之,就是全局事务ID(global transaction identifier ),最初由google实现,官方MySQL在5.6才加入该功能.GTID是事务提交时创建分配 ...
- paramiko-ssh-sftp实例
import paramiko transport = paramiko.Transport(('192.168.71.136', 22)) transport.connect(username='r ...
- 输出单项链表中倒数第k个结点——牛客刷题
题目描述: 输入一个单向链表,输出该链表中倒数第k个结点 输入.输出描述: 输入说明:1.链表结点个数 2.链表结点的值3.输入k的值 输出说明:第k个结点指针 题目分析: 假设链表长度为n,倒数第k ...
- 文件名后面加(1).text
; //在重复名称后加(序号) while (File.Exists(path)) { if (path.Contains(").")) { int start = path.La ...