BZOJ3555 [Ctsc2014]企鹅QQ[暴力+字符串hash]
菜到自闭,一道省选小水题都能给我做繁。
要求有一位不同,则对每个串每一位暴力枚举把这一位删掉,放一个分隔符,算一下hash,插表,相似的都应该会被插入同一个桶。最后把hash统计一下即可。复杂度$O(nL)$。
但是除了我以外的所有人全是把hash算好丢数组里排序,然后相似的串hash必连在一起。复杂度$O(nLlognL)$,吊打前者。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #define dbg(x) cerr << #x << " = " << x <<endl 8 using namespace std; 9 typedef long long ll; 10 typedef unsigned long long ull; 11 typedef double db; 12 typedef pair<int,int> pii; 13 template<typename T>inline T _min(T A,T B){return A<B?A:B;} 14 template<typename T>inline T _max(T A,T B){return A>B?A:B;} 15 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 16 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 17 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;} 18 template<typename T>inline T read(T&x){ 19 x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 20 while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x; 21 } 22 const ull base1=131; 23 const int P=998244353,MOD=6000011; 24 const int N=30000+5,L=200+3; 25 char s[L]; 26 ull H1,bek1; 27 int n,l,siz,len; 28 struct HASH{ 29 ull ha1[MOD];int Head[MOD],nxt[MOD],cnt[MOD],tot; 30 inline void Insert(ull x){ 31 int tmp=x%MOD,id=0; 32 for(int j=Head[tmp];j;j=nxt[j])if(x==ha1[j]){id=j;break;} 33 if(!id)ha1[++tot]=x,nxt[tot]=Head[tmp],Head[tmp]=id=tot; 34 ++cnt[id]; 35 } 36 inline int Count(){ 37 int ret=0; 38 for(register int i=1;i<=tot;++i)ret+=cnt[i]*(cnt[i]-1)/2; 39 return ret; 40 } 41 }H; 42 43 inline void read_data(){ 44 for(register int i=1;i<=n;++i){ 45 scanf("%s",s+1); 46 H1=0;bek1=1; 47 for(register int j=1;j<=l;++j)H1=H1*base1+(s[j]-47); 48 for(register int j=l;j;--j,bek1*=base1) 49 H.Insert(H1-(s[j]-147)*bek1); 50 } 51 } 52 53 int main(){//freopen("test.in","r",stdin);freopen("test.ans","w",stdout); 54 read(n),read(l),read(siz); 55 read_data(); 56 return printf("%d\n",H.Count()),0; 57 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #define dbg(x) cerr << #x << " = " << x <<endl 8 using namespace std; 9 typedef long long ll; 10 typedef unsigned long long ull; 11 typedef double db; 12 typedef pair<int,int> pii; 13 template<typename T>inline T _min(T A,T B){return A<B?A:B;} 14 template<typename T>inline T _max(T A,T B){return A>B?A:B;} 15 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 16 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 17 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;} 18 template<typename T>inline T read(T&x){ 19 x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 20 while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x; 21 } 22 const ull base1=131; 23 const int MOD=6000011; 24 const int N=30000+5,L=200+3; 25 char s[L]; 26 ull H1,bek1,ha[MOD]; 27 int n,l,siz,len,ans,cnt,tot; 28 inline void read_data(){ 29 for(register int i=1;i<=n;++i){ 30 scanf("%s",s+1); 31 H1=0;bek1=1; 32 for(register int j=1;j<=l;++j)H1=H1*base1+(s[j]-47); 33 for(register int j=l;j;--j,bek1*=base1) 34 ha[++tot]=H1-(s[j]-147)*bek1; 35 } 36 } 37 38 int main(){//freopen("test.in","r",stdin);freopen("test.ans","w",stdout); 39 read(n),read(l),read(siz); 40 read_data(); 41 sort(ha+1,ha+tot+1); 42 ha[0]=ha[1]-1; 43 for(register int i=1;i<=tot+1;++i)ha[i]^ha[i-1]?(ans+=(cnt*(cnt-1))>>1,cnt=1):++cnt; 44 printf("%d\n",ans); 45 return 0; 46 }