[CTSC2014] 企鵝QQ
阿新 • • 發佈:2018-11-06
這種東西一看就是字串hash搞。
先從前往後雜湊一遍,再從後往前雜湊一遍。
這樣我們就可以O(1)提取出去掉某一位的雜湊值。
接下來考慮計算相似字串的數目。
總數=僅在第一位不一樣的+僅在第二位不一樣的+......+僅在第L位不一樣的。
我們先列舉每一位,再把每個字串去掉這一位的雜湊值算出來,看有沒有重複的。
判重方法有很多,我用的是排序之後再計算的方法。
有個詭異的地方,算去掉某一位的雜湊值tmp的時候,如果兩邊的雜湊值相加之前不分別乘seed,會狂wa不止......
我也不知道為什麼。
1 #include<cstdio> 2#include<cstring> 3 #include<algorithm> 4 using namespace std; 5 typedef unsigned long long ull; 6 7 const int sd[2]={107,127}; 8 int n,l,s; 9 ull mul[205]; 10 ull hs[30005][205][2]; 11 int ans; 12 13 int main() 14 { 15 scanf("%d%d%d",&n,&l,&s); 16 for(int i=1;i<=n;i++) 17 { 18 char str[205]; 19 scanf("%s",str+1); 20 for(int j=1;j<=l;j++) 21 hs[i][j][0]=hs[i][j-1][0]*sd[0]+str[j]-'@'+1; 22 for(int j=l;j;j--) 23 hs[i][j][1]=hs[i][j+1][1]*sd[1]+str[j]-'@'+1; 24 } 25 ull tmp[30005]; 26 for(int i=1;i<=l;i++) 27 { 28 for(int j=1;j<=n;j++) 29 tmp[j]=hs[j][i-1][0]*sd[0]+hs[j][i+1][1]*sd[1]; 30 sort(tmp+1,tmp+n+1); 31 int nw=1; 32 for(int j=2;j<=n;j++) 33 { 34 if(tmp[j]==tmp[j-1])ans+=nw,nw++; 35 else nw=1; 36 } 37 } 38 printf("%d",ans); 39 return 0; 40 }