码迷,mamicode.com
首页 > 其他好文 > 详细

cf1200 E Compress Words(哈希)

时间:2020-02-12 16:12:06      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:math   遇到   匹配   span   style   添加   main   字符串   复杂   

题意

有n个字符串,记为s1,s2……sn,s2与s1合并,合并的方式为:s1的后缀若与s2的前缀相同,就可以重叠起来,要最长的。

举个例子:

“1333”  “33345” → “133345”

s1与s2合并后产生的字符串,再与s3合并,以此类推。

 

思路

两个字符串的子串匹配,比较容易想到哈希。

一开始想的是从左往右哈希,就是:“123” → 123,但是这样哈希的话,若要更新字符串(就是在末尾添加字符),那么前面每个位置的哈希值都要变,复杂度爆炸。

那就试试从右往左哈希,就是:“123” → 321,这样要在末尾添加字符的时候,前面的哈希值不会变,很好更新。

然后,我们就可以记录当前字符串的最后一个字符是什么,然后遍历下一个要合并进来的字符串,当遇到和末尾相同的字符时,就可以哈希看看能否匹配。

 

代码

 

#include <stdio.h>
#include <queue>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long int ll;
const int maxn = 1e6 + 10;
const ll inf = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const ll seed = 131;
char s[maxn],t[maxn];
ll sval[maxn],tval[maxn],fac[maxn];
int main()
{
    int n,lens,lent;
    char tail;
    fac[0] = 1;
    for(int i = 1;i < maxn;i++){
        fac[i] = (fac[i - 1] * seed) % mod;
    }
    while(scanf("%d",&n) != EOF){
        scanf("%s",s + 1);
        lens = strlen(s + 1);
        sval[0] = 0;
        for(int i = 1;i <= lens;i++){
            sval[i] = (((s[i] - 0) * fac[i - 1]) % mod + sval[i - 1]) % mod;
        }
        tail = s[lens];
        n--;
        ll now = 0,pos = 0;
        while(n--){
            now = pos = 0;
            scanf("%s",t + 1);
            lent = strlen(t + 1);
            for(int i = 1;i <= lent;i++){
                if(i > lens)
                    break;
                now = (((t[i] - 0) * fac[i - 1]) % mod + now) % mod;
                if(t[i] == tail){
                    if((now * fac[lens - i]) % mod == ((sval[lens] - sval[lens - i]) % mod + mod) % mod){
                        pos = i;
                    }
                }
            }

            for(int i = pos + 1;i <= lent;i++){
                sval[lens + 1] = (((t[i] - 0) * fac[lens]) % mod + sval[lens]) % mod;
                lens++;
                s[lens] = t[i];
            }
            tail = s[lens];
        }
        s[lens + 1] = 0;
        printf("%s\n",s + 1);
    }
    return 0;
}

 

cf1200 E Compress Words(哈希)

标签:math   遇到   匹配   span   style   添加   main   字符串   复杂   

原文地址:https://www.cnblogs.com/InitRain/p/12299138.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!