HDU4821 cuerdas

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;
} 

Supongo que te gusta

Origin www.cnblogs.com/qjy73/p/12498418.html
Recomendado
Clasificación