HDU4821 cuerdas
El significado de los problemas
Para una cadena \ (S \) , el sub-Q satisface las dos condiciones siguientes son el número de cadenas.
1, la longitud de la subcadena \ (N * M \) (que está representado por la \ (M \) de longitud \ (N \) cadena compensa)
2, que \ (M \) de longitud \ ( N \) caracteres en la cadena debe ser mutuamente diferentes entre sí (en cualquier posición en las dos cadenas no son idénticos a)
solución del problema
Cada cadena se da como \ (L \) , pensado \ (el Hash (R & lt ~ L) = el Hash [R & lt] -hash [-L. 1] * SUM [N] \) . Porque en \ (I \) como punto de partida para la longitud \ (N * M \) subseries, su \ (M \) de longitud \ (N \) niño fue colocado en una cadena de valor hash \ (mapa \) , si \ (map.size () == M \) , muestra que se diferencian unos de otros.
Si la enumeración de cada origen, causar TLE. Podemos utilizar la regla emulado. Para ha encontrado una subcadena, sus cadenas principales cabrito removidos, el último más una longitud \ (N \) cadena niño, ciclo continuo, puede ser una serie de sub-cadenas. Se puede dividir en la cadena original \ (N \) serie, desde \ (1 \) a \ (N \) enumeración punto de partida, la generación continua, que puede llegar a todas las subcadenas.
nota
1, el valor Hash largo abierto largo
código
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int base=131;
const int mod=1e9+7;
const int N=1e5+10;
int M,L;
char s[N];
ll Hash[N];
int len;
ll sum,ans;
map<ll,int> m;
//Hash开longlong
void getHash(char a[]){
for(int i=1;i<=len;i++){
Hash[i]=(Hash[i-1]*base%mod+s[i])%mod;
}
}
void init(){
sum=1;
for(int i=1;i<=L;i++) sum=(sum*base)%mod;
}
void solve(int st){
m.clear();
int e=st+M*L-1;
if(e>len) return;
int l=st,r=st+L-1;
for(int i=1;i<=M;i++){
ll now=(Hash[r]-Hash[l-1]*sum%mod+mod)%mod;
m[now]++;
l+=L;r+=L;
}
if(m.size()==M) ans++;
while(e+L<=len){
e+=L;
l=st;r=l+L-1;
ll now=(Hash[r]-Hash[l-1]*sum%mod+mod)%mod;
m[now]--;
if(m[now]==0) m.erase(now);
st+=L;
r=e;l=r-L+1;
now=(Hash[r]-Hash[l-1]*sum%mod+mod)%mod;
m[now]++;
if(m.size()==M) ans++;
}
}
int main(){
while(scanf("%d%d",&M,&L)!=EOF){
ans=0;
scanf("%s",s+1);
len=strlen(s+1);
getHash(s);
init();
for(int i=1;i<=L;i++){
solve(i);
}
printf("%lld\n",ans);
}
return 0;
}