hdu6096(字典树)
来源:互联网 发布:zdm cad辅助设计软件 编辑:程序博客网 时间:2024/06/10 01:47
题意是给n个字符串,然后m次查询,每次查询有给定的前缀和给定的后缀的字符串有多少个 对于每一个字符串构建字典树,但是不同于一般的构建,构建Trie树时,把每一个字符串的第1个字符放在第一个,第n-1个字符放在第二个,第2个字符放在第三个,n-2个字符放在第四个,以此类推,一共放进2n个字符,然后查询时,也把给定的前缀后缀如此处理,si,pn-1,s2,pn-2……如果前缀比后缀长或者后缀比前缀长就以特殊字符‘#’或者“*”替代,查询时则对所有的26个节点访问。 但是这样会有aaa aa aa输出为1的问题所以要先把所有的字符串和查询读入,然后对字符串根据字符串的长度排序,查询根据查询长度排序。这样在每次处理询问之前只把长度大于等于查询长度的字符串放进字典树中,就可以避开这个问题。
自己写的错误百出,最后总算a了,注意指针越界,不然会runtime errro
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <cstdlib>
using namespacestd;
char str[500005],s1[500005],s2[500005];
char nstr[500005],qstr[500005];
int ssm[500005],num;
struct nnode
{
int l,r;
}a[100005];
struct qnode
{
int r,l,rr,ll,sum;
}b[100005];
struct node
{
int flag;
node *next[26];
}*root;
bool cmp1(nnode a,nnode b)
{
return (a.r-a.l)<(b.r-b.l);
}
bool cmp2(qnode a,qnode b)
{
return (a.r-a.l+a.rr-a.ll)<(b.r-b.l+b.rr-b.ll);
}
node *build()
{
node *p = (node *)malloc(sizeof(node));
for(int i =0; i <26; i ++)
p -> next[i] =NULL;
p -> flag =0;
return p;
}
void save(char *s)
{
node *p;
p = root;
int len =strlen(s);
for(int i =0; i < len; i ++)
{
if(p ->next[s[i] -'a'] ==NULL)
p -> next[s[i] -'a'] =build();
p->next[s[i]-'a']->flag++;
p = p -> next[s[i] -'a'];
}
}
void query(node *p,int i,int len)
{
if(i==len)
{
num+=p->flag;
return;
}
if(qstr[i]=='*')
{
for(int k =0; k <26; k ++)
{
if(p->next[k]!=NULL)
{
query(p->next[k],i+1,len);
}
}
}
else
{
if(p->next[qstr[i]-'a']!=NULL)
{
query(p->next[qstr[i]-'a'],i+1,len);
}
}
}
void init_n(int j)
{
int k=0;
for(int i=a[j].l;i<a[j].r;i++)
{
nstr[k++]=str[i];
nstr[k++]=str[a[j].r-(i-a[j].l)-1];
}
nstr[k]=0;
}
void init_q(int j)
{
int len=max(b[j].r-b[j].l,b[j].rr-b[j].ll);
int l=b[j].l,ll=b[j].rr-1;
int k=0;
for(int i=0;i<len;i++)
{
if(l<b[j].r)
qstr[k++]=s1[l++];
else
qstr[k++]='*';
if(ll>=b[j].ll)
qstr[k++]=s2[ll--];
else
qstr[k++]='*';
}
qstr[k]=0;
}
int main()
{
int n,t,q;
cin>>t;
while(t--)
{
root =build();
scanf("%d %d",&n,&q);
int sum=0;
for(int i=0;i<n;i++)
{
scanf("%s",str+sum);
a[i].l=sum;
sum+=strlen(str+sum);
a[i].r=sum;
}
//printf("%s\n",str);
sort(a,a+n,cmp1);
int sum1=0,sum2=0;
for(int i=0;i<q;i++)
{
b[i].l=sum1;
b[i].ll=sum2;
scanf("%s %s",s1+sum1,s2+sum2);
sum1+=strlen(s1+sum1);
sum2+=strlen(s2+sum2);
b[i].r=sum1;
b[i].rr=sum2;
b[i].sum=i;
}
sort(b,b+q,cmp2);
int j=n-1;
memset(ssm,0,sizeof(ssm));
for(int i=q-1;i>=0;i--)
{
while(b[i].r-b[i].l+b[i].rr-b[i].ll<=a[j].r-a[j].l&&j>=0)
{
init_n(j);
save(nstr);
j--;
}
init_q(i);
node *p;
p = root;
int len =strlen(qstr);
num=0;
query(p,0,len);
ssm[b[i].sum]=num;
}
for(int ii=0;ii<q;ii++)
printf("%d\n",ssm[ii]);
}
return0;
}
唉真难啊,这道题写了一个下午加一个晚上,各种错,交了n次,感觉自己好笨
- hdu6096(字典树)
- HDU6096 string(字典树)
- HDU6096 String(Trie树)
- HDU6096 ac自动机+fail树
- hdu6096 String AC自动机
- hdu6096 String【AC自动机】
- 字典树
- 字典树
- 字典树
- 字典树
- 字典树
- 字典树。。
- 字典树
- 字典树
- 字典树
- 字典树
- 字典树
- 字典树
- 第十二天
- select函数监控一个或多个文件描述符状态程序
- SQL Server 无法删除发布服务解决方法
- C语言连接mysql数据库
- linux的mariadb数据库
- hdu6096(字典树)
- 关注国情民情,从身边做起
- 关注民生民情
- 使用SQL Server发布数据库快照遇到错误:对路径“xxxxx”访问被拒绝的解决方法
- App的手势密码你做对了吗?
- 冒泡排序
- webpack---webpack构建vue多页面框架(二、webpak.config.js)
- wordPress使用记录
- Elasticsearch实现原理分析-1