[bzoj1819] [JSOI]Word Query电子字典
正解是trie树。。。在树上跳来跳去什么的
然而在企鹅qq那题的影响下我写了hash。。。
添加一个字母到一个串,就相当于另一个串删对应位置上的字母。
改变某个位置上的字母,就相当于两个字符串删掉同一个位置上的字母。
所以要记录的东西也不多。。存一下每个串删掉每个位置上的字母后的hash值并排序,然后查询的时候二分一下就行了。
但要注意的是,两个字符串可能有多种编辑方式。。。比方说字符串cccc,分别删掉四个位置上的字母后得到的都是ccc。。
所以一开始要再去一下重。(要不是老司机提醒我还不知道要调多久TAT
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define ull unsigned long long
using namespace std;
const int maxn=;
ull mp[][maxn];
ull b[],jc[],pre[];
ull map[*maxn];
int len[maxn],num[];
int i,j,k,n,m,l,r,mid,cnt,ans;
char s[];
inline int getl(int x,ull v){
for(l=,r=num[x];l<r;)
if(mp[x][mid=(l+r)>>]<v)l=mid+;else r=mid;
return mp[x][l]==v?l:;
}
inline int getr(int x,ull v){
for(l=,r=num[x];l<r;)
if(mp[x][mid=(l+r+)>>]<=v)l=mid;else r=mid-;
return mp[x][l]==v?l:;
}
inline int get(int ull v){
int posl;
for(l=,r=cnt;l<r;)
if(map[mid=(l+r)>>]<v)l=mid+;else r=mid;
if(map[l]!=v)return ;
if(map[l+]!=v)return ;
posl=l;
for(l=posl,r=cnt;l<r;)
if(map[mid=(l+r+)>>]<=v)l=mid;else r=mid-;
return l-posl+;
}
int main(){
register int j;
scanf("%d%d",&n,&m);
for(i=jc[]=;i<=;i++)jc[i]=jc[i-]*;
int mx=;num[]=n;
for(i=;i<=n;i++){
scanf("%s",s);len[i]=strlen(s);
for(j=;j<=len[i];j++)pre[j]=pre[j-]*+s[j-];
for(j=;j<=len[i];j++)
mp[j][++num[j]]=pre[len[i]]-pre[j]*jc[len[i]-j]+pre[j-]*jc[len[i]-j];
mp[][i]=pre[len[i]];
mx=max(mx,len[i]);
for(j=;j<=len[i];j++)b[j]=mp[j][num[j]];
sort(b+,b++len[i]);
for(j=len[i];j;j--)if(j==len[i]||b[j+]!=b[j])map[++cnt]=b[j];//,printf(" %lld\n",b[j]);
// printf("! %lld\n",mp[1][num[1]]);
}
for(i=;i<=mx;i++)sort(mp[i]+,mp[i]++num[i]);
sort(map+,map++cnt);
// for(i=0;i<=mx;i++){
// for(j=1;j<=num[i];j++)printf(" %lld",mp[i][j]);puts("");
// }
ull tmp;
while(m--){
scanf("%s",s);int len=strlen(s);
for(j=;j<=len;j++)pre[j]=pre[j-]*+s[j-];
if((k=getl(,pre[len]))){puts("-1");continue;} ans=get(pre[len]);//printf(" %d\n",ans);
for(j=;j<=len;j++){
tmp=b[j]=pre[len]-pre[j]*jc[len-j]+pre[j-]*jc[len-j];
if((k=getl(j,tmp)))ans+=getr(j,tmp)-k+;
} sort(b+,b++len);
for(j=len;j;j--)
if(j==len||b[j+]!=b[j])
if((k=getl(,b[j])))
ans+=getr(,b[j])-k+; printf("%d\n",ans);
}
return ;
}
[bzoj1819] [JSOI]Word Query电子字典的更多相关文章
- BZOJ1819 [JSOI]Word Query电子字典 Trie
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1819 题意概括 字符串a与字符串b的编辑距离是指:允许对a或b串进行下列“编辑”操作,将a变为b或 ...
- 2786: [JSOI]Word Query电子字典
2786: [JSOI]Word Query电子字典 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 3 Solved: 3[Submit][Statu ...
- 1819: [JSOI]Word Query电子字典
1819: [JSOI]Word Query电子字典 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 729 Solved: 238[Submit][S ...
- bzoj 1819: 电子字典 Trie
题目: Description 人们在英文字典中查找某个单词的时候可能不知道该单词的完整拼法,而只知道该单词的一个错误的近似拼法,这时人们可能陷入困境,为了查找一个单词而浪费大量的时间.带有模糊查询功 ...
- 洛谷P4407 [JSOI2009]电子字典
题目描述 人们在英文字典中查找某个单词的时候可能不知道该单词的完整拼法,而只知道该单词的一个错误的近似拼法,这时人们可能陷入困境,为了查找一个单词而浪费大量的时间.带有模糊查询功能的电子字典能够从一定 ...
- 改变word的语言字典
改变word的语言字典 上周末看论坛有人提出否有方法用代码改变word的语言字典,因为默认的语言会影响现用语言输入的拼写器和其他校对工具.我们的Spire.doc正好支持,正好闲来无事所以我用西班牙语 ...
- [LeetCode] Longest Word in Dictionary 字典中的最长单词
Given a list of strings words representing an English Dictionary, find the longest word in words tha ...
- 6.C语言文件操作之英语电子字典的实现,dos版
多的不说,直接上代码: 里面涉及的字典文件在这:这是传送门,下载下来以后把该文件放在工程目录下即可 #define _CRT_SECURE_NO_WARNINGS #include <stdio ...
- [leetcode]720. Longest Word in Dictionary字典中最长的单词
b.compareTo(a) 这个函数是比较两个值得大小,如果b比a大,那么返回1 如果小,那么返回-1,相等返回0 如果比较的是字符串,那么比较字典编纂顺序,b靠前返回-1,靠后返回1 这个题的核心 ...
随机推荐
- Docker Stack 集群部属服务
Docker越来越成熟,功能也越来越强大.使用Dokcer Stack做服务集群也是非常的方便,docker 自己就提供了负载功能,感觉很方便,就想给大家分享一下,做一个简单的教程. 环境 我是用了两 ...
- CSS line-height概念与举例
本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/37 定义 两行文字基线之间的距离. 基线的大体位置 基线的位置可 ...
- Spark源码剖析(六):Worker原理与源码剖析
上篇文章我们剖析了Master的原理和源码,知道了当Master使用资源分配算法将资源分配完成后,就会给对应的Worker发送启动Driver或者Executor的消息,那么Worker收到这些消息后 ...
- java-FFmpeg(一) 实现视频的转码和截图功能
FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件).它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/视频编解码库l ...
- inux_异常_07_ftp查看不到文件列表
二.参考资料 1.Linux关于ftp查看不到文件列表的问题
- c#代码技巧
1.#region #endregion 1.#region 是一个分块预处理命令,主要用于编辑代码分段,在编译时会自动屏蔽,同时该指令可以使代码在VS代码编辑器中折叠或展开: 2.#region必须 ...
- 房上的猫:StringBuffer类
一.使用StringBuffer类 StringBuffer类位于java.lang包中,是String类的增强类 步骤: 1.声明StringBuffer对象并初始化 StringBuffer s ...
- margin和padding的区别和用法
margin和padding的区别和用法 什么是margin.padding? marigin:就是外边距.padding:就是内边距.怎么就容易记住两者呢? 马蓉大家都知道吧,给王宝强带帽子的那位, ...
- Java笔记:Java 流(Stream)、文件(File)和IO
更新时间:2018-1-7 12:27:21 更多请查看在线文集:http://android.52fhy.com/java/index.html java.io 包几乎包含了所有操作输入.输出需要的 ...
- JS中typeof和instanceof用法区别
typeof和instanceof都可以用来判断变量 1.typeof用以获取一个变量或者表达式的类型,typeof一般只能返回如下几个结果: number,boolean,string,functi ...