zoukankan      html  css  js  c++  java
  • 【题解】【bzoj1819】【JSOI】Word Query电子字典

    屑人屑题解。

    做完去题解区翻了一波,全是没想到的Trie。

    表示只会字符串hash /kel。

    懒得写格式了。

    首先,维护两个umap(其实是代替umset的),一个是单词表,一个是变化过的单词表。

    变化过的单词表分两种:原单词删去一个字母和原单词把一个字母改成 $

    查询的时候先看单词表里有没有,没有的话,先直接在变化表里查一个,再选一个字母删掉再查一个,再把一个字母改成 $ 再查一个。

    注意,为了防止出现一些奇奇怪怪的重复,插入和查询时需要一个uset来去重

    为什么不直接用umap存字符串而还要先hash再存?空间问题~

    上代码吧

    #include<bits/stdc++.h>
    #pragma GCC optimize("Ofast",3,"inline")
    using namespace std;
    typedef pair<unsigned long long,unsigned long long>ul;//双哈希,稳
    struct hasher{
    	size_t operator()(const ul p)const{
    		return (hash<unsigned long long>()(p.first)*13148274ull+hash<unsigned long long>()(p.second))%86850899ull;
    	}
    };
    unordered_map<ul,int,hasher>umap,dict;
    ul strhash(string x){
    	unsigned long long ret1=0,ret2=0;
    	for(auto i:x)ret1=(ret1*INT_MAX+i)%23333333;
    	for(auto i:x)ret2=ret2*998244353ull+i;
    	return make_pair(ret1,ret2);
    }
    void insert(string x){
    	++dict[strhash(x)];
    	unordered_set<ul,hasher>uset;
    	for(unsigned i=0;i<x.length();++i){
    		auto p(x);
    		p[i]='$';
    		++umap[strhash(p)];
    	}
    	for(unsigned i=0;i<x.length();++i){
    		auto p(x);
    		p.erase(p.begin()+i);
    		uset.insert(strhash(p));
    	}
    	for(auto w:uset)++umap[w];
    }
    int query(string x){
    	const ul w=strhash(x);
    	if(dict[w])return -1;
    	unordered_set<ul,hasher>uset;
    	int ans=umap[w];
    	for(unsigned i=0;i<x.length();++i){
    		auto p(x);
    		p.erase(p.begin()+i);
    		uset.insert(strhash(p));
    	}
    	for(unsigned i=0;i<x.length();++i){
    		auto p(x);
    		p[i]='$';
    		ans+=umap[strhash(p)];
    	}
    	for(auto l:uset)ans+=dict[l];
    	return ans;
    }
    int main(){
    	int n,m;cin>>n>>m;
    	for(int i=1;i<=n;++i){
    		string x;cin>>x;
    		insert(x);
    	}
    	for(int i=1;i<=m;++i){
    		string x;cin>>x;
    		cout<<query(x)<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    C# 动态创建SQL数据库(一)
    在Winform中菜单动态添加“最近使用文件”
    转(C# 类似右键菜单弹出窗体)
    为什么不能用Abort退出线程
    C# GDI绘制波形图
    转(C# 实现生产者消费者队列)
    为字段设置初始值
    闲话资源管理
    正确使用 new 修饰符
    减少装箱与拆箱
  • 原文地址:https://www.cnblogs.com/unyieldingtrilobite/p/13721056.html
Copyright © 2011-2022 走看看