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的更多相关文章

  1. 2017多校第6场 HDU 6096 String AC自动机

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6096 题意:给了一些模式串,然后再给出一些文本串的不想交的前后缀,问文本串在模式串的出现次数. 解法: ...

  2. HDU 6096 String(AC自动机+树状数组)

    题意 给定 \(n\) 个单词,\(q\) 个询问,每个询问包含两个串 \(s_1,s_2\),询问有多少个单词以 \(s_1\) 为前缀, \(s_2\) 为后缀,前后缀不能重叠. \(1 \leq ...

  3. HDU 6096 String (AC自动机)

    题目链接 Problem Description Bob has a dictionary with N words in it. Now there is a list of words in wh ...

  4. 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 ...

  5. HDU 6096 String (AC自动机)

    题意:给出n个字符串和q个询问,每次询问给出两个串 p 和 s .要求统计所有字符串中前缀为 p 且后缀为 s (不可重叠)的字符串的数量. 析:真是觉得没有思路啊,看了官方题解,真是好复杂. 假设原 ...

  6. HDU 6096 String 排序 + 线段树 + 扫描线

    String Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others) Problem De ...

  7. HDU 3374 String Problem (KMP+最大最小表示)

    HDU 3374 String Problem (KMP+最大最小表示) String Problem Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  8. 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 ...

  9. HDU 3374 String Problem(KMP+最大/最小表示)

    String Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

随机推荐

  1. PAT B1018.锤子剪刀布(20)

    一个没有通过,不知道为何 #include <cstdio> int change(char c) { if(c == 'B') return 0; if(c == 'C') return ...

  2. C++类的对象和类的指针的区别

    #include <iostream> #include <string> using namespace std; class Student { public: stati ...

  3. 一篇文章理解JS继承——原型链/构造函数/组合/原型式/寄生式/寄生组合/Class extends

    说实在话,以前我只需要知道"寄生组合继承"是最好的,有个祖传代码模版用就行.最近因为一些事情,几个星期以来一直心心念念想整理出来.本文以<JavaScript高级程序设计&g ...

  4. 关于win10安卓真机调试无法找到设备的问题

    之前在win10系统上调试安卓设备,usb接好了,结果居然没有找到设备. 一般出现这种情况可能是电脑的驱动没装好. 于是找了驱动人生大佬来诊断,确实是少了安卓usb驱动. 正常来说用驱动人生装个usb ...

  5. webpack编写一个plugin插件

    插件向第三方开发者提供了 webpack 引擎中完整的能力.使用阶段式的构建回调,开发者可以引入它们自己的行为到 webpack 构建流程中.创建插件比创建 loader 更加高级,因为你将需要理解一 ...

  6. spring-cloud 学习二 服务发现

    注册中心服务发现的例子 添加module pom文件如下 <?xml version="1.0" encoding="UTF-8"?> <pr ...

  7. JSON和AJAX基础

    前一段时间做老师留的企业图谱作业,和查询功能都需要用到AJAX .然后做爬虫的时候发现好多网站都用到的是页面的局部刷新,也就是发送的AJAX请求.就去学了一下.简单总结 什么是 JSON ? JSON ...

  8. UDP通信简单 小结

    Android手机版和电脑版 效果图: 通过WiFi局域网 电脑和手机连接通信. 电脑版本和手机版本使用了相同的消息发送头协议, 可以相互接收消息. 若有做的不好的地方还希望大家指导一下. 1. 手机 ...

  9. redis的keys常用操作及redis的特性

    redis的keys常用操作 1.获得所有的keys: keys * 2.可以模糊查询 keys:keys  my* 3.删除keys:del mymkey1 mykey2 4.是否存在keys:ex ...

  10. Express bodyParser中间件使用方式

    bodyParser中间件用来解析http请求体,是express默认使用的中间件之一. 1.这个模块提供以下解析器 (1) JSON body parser (2) Raw body parser ...