【bzoj4084】[Sdoi2015]bigyration hash

bzoj没有题面,题面在vijos。

所以说读入char再丢给string并不会慢…

短串扔到hash表里。
长串的前半部分复制一份,然后在上面跑,若长串的后半部分出现过,则答案加上后面的hash值的出现次数。

写了双hash+挂链表,因为写了指针,并且双hash常数大,所以TLE+MLE,还有莫名其妙的WA…………

自然溢出+map在vijos上就是过不了……T两个点,不过在bzoj还是能A的。

看题解有人写的在bool数组中若已被占用则往后跳…在bzoj实测表现和map差不多…vijos也是T两个点…

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;

typedef unsigned long long ULL;
typedef long long LL;
const int SZ = 4000010;
const int base = 13331;

string S1[SZ],S2[SZ];

map<ULL,int> h;

ULL hash[SZ],mi[SZ];

ULL gethash(string s)
{
    ULL ans = 0;
    for(int i = 0;i < s.length();i ++)
        ans = ans * base + s[i] - 'a' + 1;
    return ans;
}

ULL getstr(int l,int r)
{
    int len = r - l + 1;
    return hash[r] - hash[l - 1] * mi[len];
}

char s[SZ];

void read(char s[])
{
    memset(s,0,sizeof(s));
    int tot = 0;
    char a = getchar();
    for(;a < 'a' || a > 'z';a = getchar());
    for(;a >= 'a' && a <= 'z';a = getchar())
        s[tot ++] = a;
}

int main()
{
    int n,m,len1,len2;
    scanf("%d%d%d%d",&n,&m,&len1,&len2);
    mi[0] = 1;
    for(int i = 1;i <= len1 + len2;i ++)
        mi[i] = mi[i - 1] * base;
    for(int i = 1;i <= n;i ++)
        read(s),S1[i] = s;
    for(int i = 1;i <= m;i ++)
        read(s),S2[i] = s;

    if(len1 < len2) 
        swap(S1,S2),swap(n,m),swap(len1,len2);

    for(int i = 1;i <= m;i ++)
        h[gethash(S2[i])] ++;

    int len = (len1 + len2) >> 1;
    LL ans = 0;
    for(int i = 1;i <= n;i ++)
    {
        for(int j = 0;j < len * 2;j ++)
            hash[j + 1] = hash[j] * base + S1[i][j % len] - 'a' + 1;
        ULL x = 0;
        for(int j = len;j < len1;j ++)
            x = x * base + S1[i][j] - 'a' + 1;
        for(int j = 1;j <= len;j ++)
        {
            ULL y = getstr(j,j + len1 - len - 1);
            if(x == y)
            {
                ULL a = getstr(j + len1 - len,j + len - 1);
                ans += h[a];
            }
        }
    }
    printf("%lld\n",ans);
    return 0;
}

你可能感兴趣的:(【bzoj4084】[Sdoi2015]bigyration hash)