Codeforces662C【字符串hash维护+DP】

来源:互联网 发布:英语翻译网络主播 编辑:程序博客网 时间:2024/05/29 19:01

思路:
每个串可以用多次且每个串的长度<=1000,那么就简单了。
字符串可以字典树或者hash维护,然后暴搞就好了,记录一下路径,然后输出就好了。
1e6的字符串hash复杂度还是可观的
复杂度:O(N*W)

//#pragma comment(linker, "/STACK:102400000,102400000")#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;typedef long long LL;const int Maxm = 1e5 + 10;const int Maxn = 1e4 + 10;const LL p = 31;const LL mod = 1e9 + 7;char s1[Maxn], s2[Maxm][1010];LL h1[Maxn], f[Maxn];map<LL, LL>mp;int n, m, Mx;void init(){    h1[0] = 0;    f[0] = 1;    for(int i=1;i<=10000;i++) f[i] = f[i-1] * p % mod;}LL idx(char x){    if(x >= 'A' && x <= 'Z') return (long long)(x - 'A' + 1);    return (long long)(x - 'a' + 1);}LL Hash(char s[]){    LL temp = 0;    int len = strlen(s+1);    Mx = Mx < len ? len : Mx;    for(int i=1;i<=len;i++)        temp=(temp*p+idx(s[i])) % mod;    return temp;}LL get_L_to_R(int Left, int Right, LL has[]){    return (has[Right] - has[Left-1]* f[Right - Left + 1] % mod + mod) % mod;}void jud(LL x, LL y){    if(mp.find(x) != mp.end()) return;    mp[x] = y;}int dp[Maxn], pre[Maxn], ans[Maxn];int main(){    init();    scanf("%d%s", &n, s1+1);    int len = strlen(s1+1);    reverse(s1+1, s1+len+1);    for(int i=1;i<=len;i++)        h1[i]=(h1[i-1]*p+idx(s1[i])) % mod;    scanf("%d", &m);    Mx = 0;    for(int i=1;i<=m;i++){        scanf("%s", s2[i]+1);        jud(Hash(s2[i]), i);    }    memset(dp, 0, sizeof(dp));    pre[0] = -1;    dp[0] = 1;    LL has1, has2;    for(int i=1;i<=len;i++){        for(int j=1;j<=Mx && i-j>=0;j++){            if(dp[i-j]){                has1 = get_L_to_R(i-j+1, i, h1);                if(mp.find(has1) != mp.end()){                    pre[i] = i-j;                    ans[i] = mp[has1];                    dp[i] = 1;                    break;                }            }        }    }    int pos = len;    while(pre[pos] != -1){        printf("%s ",s2[ans[pos]] + 1);        pos = pre[pos];    }    return 0;}
原创粉丝点击