【題解】【bzoj1819】【JSOI】Word Query電子字典
阿新 • • 發佈:2020-09-23
屑人屑題解。
做完去題解區翻了一波,全是沒想到的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; }