しかし小さな缶学校図書館の管理者、そして今、彼は非常に困難な作業を継承しています。学校はいくつかの材料を必要とするので、記事の検査における主な必要性は、
いくつかの情報を検索します。小物にセラー総カカオN、文字列として各物品。さて、社長がこのような言葉を見つけるために彼を必要とし、それは少なくとも、ある
記事に登場したこの記事のM Nの記事、およびワード長L. しかし、作業負荷が非常に大きいですが、社長は、このタスクを完了するために少しココア緊急の必要があります
。今、彼はあなたがこの骨の折れる作業を完了するためのプログラム記述する必要がある、あなたになった
入力
、13の正の整数N、M、L行の記事の数を表し、単語は、各単語の長さとMの記事では、少なくとも表示されます。
物品を表す文字列の次のNライン。
1≤N、M≤2000、L≤1000。各記事の長さが1000より大きくない、小文字である
出力
のみ一行、検索条件を満足する発現単語の数。
入力サンプル
3 2 2
NOIPの
istudycppの
imacppstudent
出力サンプル
5つの
//これらの5つの単語がある:ST、TU、UD、PP 、CP。
#include <iostreamの> する#include <stdio.hに> する#include <string.hの> 名前空間STDを使用して、 ロングロングLLのtypedef、 CONST INT MAXN = 2005; CONST INT MAXM = 1000005; CONST INT MINMOD = 999 973; CONST = LL MaxMod 499999999999993ll、 ノードストラクト { int型NO、CNT、ワード文書番号は、CNTは、ワードの出現回数である// NOである LL sが; //れる言葉hashh値 次INT; //が開いハッシュと競合を解決 } H [ MAXM]; ; INT N、M、L、TOT、ANS 第INT [MAXM]; CHAR STR [MAXN] [MAXN]; ボイド追加(Uはint、int型のX、LL S) xの資料の//短いhashh値が表示され、U、Sワード長hashh付加価値hashhテーブル { ++ TOT; H [TOT] .S = S; H [TOT = .CNT 1; H [TOT] .NO = X。 H [TOT] .next =最初の[ U]。 最初の[U] = TOT; { } ボイドhashh(X int型、U int型、LL S) {int型I; のために(私はまず= [U]は;! I 0 =; Iは、[I] .nextをH =)を IF(S == H [I]。 S)//上テーブルhashhに現れる { IF(H [I] .NO == x)をリターン; //は、xに現れる物品では、制御できません ; H [I] = X .NO Hを[ I] .CNT ++;数//発生プラス1つの。 リターン; } 追加(U、X、S); } INITを無効() { int型I; scanfの( "%D%D%D"、&N、&M&L) ; のため(I = 1; I <= N; I ++) scanfの( "%のS"、&STR [I]); ANS = 0; } ボイドワーク() {int型I、J、U、K、K1; LL S 、K2; ; K1 = K2 = 1。 ため(J = 0; J <-L 1; J ++) K2 = K2 * 26%MaxMod。 K1 = K1 * 26%MinMod; //数量级 以下のための式(I = 1; I <= TOT; I ++) } のためには、(i 1 =; I <= N; I ++) { U = S = 0。 (; J <L J ++ J = 0)のための { U =(U * 26 + STR [I] [J])%MinMod; //短hashh值 S =(S * 26 + STR [I] [J] )%MaxMod; //长hashh值 } hashh(I、U、S)。 K = strlenを(STR [I])。 (; J <K、J = L J ++)のために { U =((U-STR [I] [JL] * K1)%MinMod + MinMod)%MinMod; //前面去一位后面加一位 S(= (S-STR [I] [JL] * K2)%MaxMod + MaxMod)%MaxMod。 U =%MinMod(U 26 + STR [I] [J] *)と、 S =(S * 26 + STR [I] [J])%MaxMod。 hashh(I、U、S)。 } } } ボイド出力() { I int型。 printf( "%dの\ n"は、ANS)。 (H [I] .CNT> = M)++ ANS場合。 } INTメイン(ボイド) { INIT()。 作業(); 出力(); 0を返します。 }
#include<bits/stdc++.h>
#define ll long long
#define mod 28282789
#define L 1001
using
namespace
std;
inline
void
read(
int
&x){
int
datta=0;
char
chchc=
getchar
();
bool
okoko=0;
while
(chchc<
'0'
||chchc>
'9'
){
if
(chchc==
'-'
)okoko=1;chchc=
getchar
();}
while
(chchc>=
'0'
&&chchc<=
'9'
){datta=datta*10+chchc-
'0'
;chchc=
getchar
();}
x=okoko?-datta:datta;
}
int
n,m,l,len,times[mod+10],ans;
int
clear[L],nc;
ll base=26,q[L],hx[L];
char
c[L];
bool
did[mod+10];
ll fk(
int
a,
int
b){
return
(hx[b]-(hx[a-1]*q[b-a+1])%mod+mod)%mod;}
int
main(){
read(n),read(m),read(l);q[0]=1;
for
(
int
i=1;i<=L;i++)q[i]=(q[i-1]*base)%mod;
for
(
int
i=1;i<=n;i++){
scanf
(
"%s"
,c+1);
len=
strlen
(c+1);
for
(
int
i=1;i<=len;i++)hx[i]=(hx[i-1]*base+c[i]-
'a'
+1)%mod;
for
(
int
i=1;i+l-1<=len;i++){
ll tp=fk(i,i+l-1);
if
(!did[tp]){
did[tp]=
true
;clear[++nc]=tp;
if
(++times[tp]==m)ans++;
}
}
for
(
int
i=1;i<=nc;i++){did[clear[i]]=
false
;}
nc=0;
}
printf
(
"%d\n"
,ans);
return
0;
}