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*/

  

转载于:https://www.cnblogs.com/FxxL/p/7346306.html

hdu 6096 String相关推荐

  1. HDU 6096 String (AC自动机)

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

  2. HDU 6194 string string string

    HDU 6194 输入一个字符串,求出现K次得子串个数 我的做法是求出大于等于K次的子串个数-大于等于K+1次的子串个数 #include <stdio.h> #include <s ...

  3. HDU 2476 String painter (区间DP)

    题意:给出两个串a和b,一次只能将一个区间刷一次,问最少几次能让a=b 思路:首先考虑最坏的情况,就是先将一个空白字符串刷成b需要的次数,直接区间DP[i][j]表示i到j的最小次数. 再考虑把a变成 ...

  4. HDU - 6629 string matching(扩展KMP)

    题目链接:点击查看 题目大意:给出一个字符串 s 和一个暴力程序,用于求解 s 的每个后缀和原字符串的最长公共前缀,现在问一共需要执行多少次比较操作 题目分析:首先肯定不能暴力去模拟,时间复杂度n*n ...

  5. HDU - 6194 string string string(后缀数组+RMQ+容斥)

    题目链接:点击查看 题目大意:给出一个字符串和一个数字 k,问字符串中出现次数恰好等于 k 次的字串有多少个 题目分析:在跑完后缀数组后,我们可以用sa数组求解,具体做法是枚举起点,找长度为 k 的s ...

  6. HDU - 3374 String Problem(最小表示法+最大表示法+KMP的next数组)

    题目链接:点击查看 题目大意:给出一个字符串,现在问字符串不断向左循环所能形成的n个字符串中,字典序最小和最大的字符串的编号为多少,分别有多少个 题目分析:字符串最小表示法的模板题,证明和模板都是看大 ...

  7. HDU - 4821 String(字符串哈希+优化)

    题目链接:点击查看 题目大意:给出一个m和l,还有一个字符串,问在s中所有长度为m*l的连续子字符串中,有多少个满足条件的子字符串 这里的满足条件指的是,长度为m*l的子字符串,可以分成m个长度为l的 ...

  8. hdu P3374 String Problem

    今天又在lyk大佬的博客学会了--最小表示法(异常激动 发篇题解纪念一下 说在前面:给luogu提个建议最小表示法的题太少了,都被hdu抢去了!!! 我们先看一下题目 看完后可以用一个字概括--蒙,两 ...

  9. hdu 6194string string string 后缀自动机

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6194 查询原串中出现次数等于k次的子串数量.需要用到基数排序. 构造完后缀自动机之后将节点按照maxl ...

最新文章

  1. 数组第一个值_Excel公式技巧69:查找第一个非空值
  2. input[type=checkbox] ; input[type=radio] 改变默认样式
  3. Java中Synchronized的用法
  4. pydev-python 链接mysql数据库(mac系统)
  5. Boost:boost::bimaps::multiset_of的测试程序
  6. JSON用于多态Java对象序列化
  7. matlab subplot同时显示多幅图像
  8. 【Flink】Flink Row和RowData的区别
  9. 马哥 mysql教学笔记_【马哥linux学员学习笔记】MySQL多实例详解
  10. Server concepts 详解
  11. keytool-JDK导入证书
  12. python割圆法求“圆周率”
  13. mapper扫描问题(Invalid bound statement (not found))
  14. 计算机网络放大器的作用,运算放大器工作原理是什么?
  15. java连接HDFS+Kerberos配置参数示例
  16. c语言素数筛法与分解素因数,质因数分解及代码:
  17. docker基础(11):自定义tomcat镜像启动与访问
  18. C语言中entry用法,Tkinter模块(3)-Entry
  19. Ubuntu server 16.04 修改IP地址
  20. 儿童高脚椅、餐椅安全标准ASTM F404

热门文章

  1. 选择用户-显示已选用户
  2. 如何使用 WinUSB 与 USB 设备 (USBDevice) 通信
  3. 在Outlook中设置类似Foxmail带日期的签名
  4. springboot内置浏览器_SpringBoot快速搭建
  5. redis 备份导出rdb_Redis持久化知识点—RDB+AOF ,你了解多少
  6. linux命令mov,汇编指令_Y-linuz-linux-w_新浪博客
  7. 剑灵电五服务器位置,选对服务器很重要 剑灵新手选服攻略
  8. java多线程的底层实现_多线程的底层实现机制 - 欢迎来到古怪匹诺曹的开发世界 - OSCHINA - 中文开源技术交流社区...
  9. Python机器学习:梯度下降法005梯度下降法和数据标准化
  10. 微信小程序 服务器触发事件,微信小程序组件间通讯与事件