关于Hash:我不会
所以我们需要map
一、字符串Hash
就是一个公式
大概长这样
Hash(s)=(i=1∑len(s)s[i]⋅blen−i)modm
看上去是不是很抽象?
因为我不会美观地写公式(技术硬伤)
所以引入大佬的博客
不用多说,上代码
#include<bits/stdc++.h> using namespace std; namespace _mzf { #define ull unsigned long long ull n,ans=1; ull base=131; const ull N=1e4+100; char s[N]; ull a[N]; int prime=233317; ull mod=21237044013013795711; ull hash(char s[]) { int len=strlen(s); ull ans=0; for(int i=0;i<len;i++) ans=(ans*base+(ull)s[i])%mod;//+prime return ans; } void mzfmain() { cin>>n; for(int i=1;i<=n;i++) { scanf("%s",s); a[i]=hash(s); } sort(a+1,a+1+n); for(int i=1;i<n;i++) if(a[i]!=a[i+1]) ans++; cout<<ans<<endl; } } int main() { _mzf::mzfmain(); return 0; }
二、裸题
可以一边扫一边哈希
轻松水过
#include<bits/stdc++.h> using namespace std; namespace _mzf { #define ull unsigned long long ull n,ans=1; ull base=131; const ull N=1e4+100; char s[N]; ull a[N]; int prime=233317; ull mod=21237044013013795711; ull hash(char s[]) { int len=strlen(s); ull ans=0; for(int i=0;i<len;i++) ans=(ans*base+(ull)s[i])%mod;//+prime return ans; } void mzfmain() { cin>>n; for(int i=1;i<=n;i++) { scanf("%s",s); a[i]=hash(s); } sort(a+1,a+1+n); for(int i=1;i<n;i++) if(a[i]!=a[i+1]) ans++; cout<<ans<<endl; } } int main() { _mzf::mzfmain(); return 0; }
关于子串Hash,我从来就没写对过,所以跳过
接下来让我们领略map的魅力
二、map
底层是一个红黑树(又是本蒟蒻不会的算法QAQ)
可以当成一个下表可以是各种乱七八糟东西的数组
常用于离散化和字符串(骗分或减少码量)
我爱map
话不多说直接开骗
一、刚才的一道大水题
#include<bits/stdc++.h> using namespace std; namespace _mzf { int n,ans; map<string,int> a; string s; void mzfmain() { cin>>n; for(int i=1;i<=n;i++) { cin>>s; if(!a[s]) ans++,a[s]=1; else continue; } cout<<ans<<endl; } } int main() { _mzf::mzfmain(); return 0; }
轻松骗得满分,mapyyds
二、阅读理解
#include<bits/stdc++.h> using namespace std; namespace _mzf { map< string,map<int,int> > a; int n,m; string s; void mzfmain() { cin>>n; for(int i=1;i<=n;i++) { int x; cin>>x; while(x--) { cin>>s; a[s][i]=1; } } cin>>m; for(int i=1;i<=m;i++) { cin>>s; for(int j=1;j<n;j++) if(a[s][j]) cout<<j<<" "; if(a[s][n]) cout<<n; cout<<endl; } } } int main() { _mzf::mzfmain(); return 0; }
二维map骗90,爽