同WA了5,9,13,14,17,求大佬指点
查看原帖
同WA了5,9,13,14,17,求大佬指点
236526
Zdxfgre楼主2020/8/12 12:55

用的是回文树加kmp前缀和的做法,调来调去都是wa这几个点,求大佬看看

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn = 5e6 + 10;
int ch[maxn][26], fail[maxn];
ll cnt[maxn];
ll s[maxn], len[maxn];
int last, sz, n;
int newnode(int x)
{
    for (int i = 0; i < 26;++i)
    {
        ch[sz][i] = 0;
    }
    cnt[sz] = 0;
    len[sz] = x;
    return sz++;
}
void init()
{
    sz = 0;
    newnode(0);
    newnode(-1);
    last = 0, n = 0;
    fail[0] = 1;
    s[0] = -1;
}
int getfail(int u)
{
    while(s[n-len[u]-1]!=s[n])
        u = fail[u];
    return u;
}
int pos[maxn];
void add(int c)
{
    s[++n] = c;
    int u = getfail(last);
    if(!ch[u][c])
    {
        int np = newnode(len[u] + 2);
        fail[np] = ch[getfail(fail[u])][c];
        ch[u][c] = np;
    }
    last = ch[u][c];
    pos[last] = n;
    cnt[last]++;
}
void count()
{
    for (int i = sz - 1; i >= 0;--i)
    {
        cnt[fail[i]] += cnt[i];
    }
}
ll nxt[maxn];
void getnxt(string x)
{
    nxt[0] = -1;
    int j=0,k=-1;
    while(j<x.length())
    {
        if(k==-1||x[j]==x[k])
            nxt[++j]=++k;
        else k=nxt[k];
    }
    return;
}
ll sum[maxn];
ll sum2[maxn];
void kmp(string s,string t)
{
    int j=0;
    for(int i=0;i<=s.length();++i)
    {
        if(j==t.length())
            sum[i] = 1;
        while(s[i]!=t[j]&&j!=-1)
            j=nxt[j];
        ++j;
    }
   // if(j==t.length())
  //      sum[s.length()] = 1;
    return;
}
const ll mm = 4294967296;
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    string a, b;
    cin >> a >> b;
    init();
    ll le = a.length();
    for (int i = 0; i < le;++i)
    {
        add(a[i] - 'a');
    }
    count();
    ll ans = 0;
    getnxt(b);
    kmp(a, b);
    ll cc = b.length();
    for(int i=1;i<=a.length();++i)
    {
        sum2[i] = sum2[i - 1] + sum[i];
   //     cout << sum2[i] << ' ';
    }
   // cout << endl;
 //   for(int i=0;i<a.length();++i)
     //   cout << a[i] << ' ';
   // cout << endl;
    for (int i = 2; i < sz;++i)
    {
        if(len[i]%2==1&&len[i]>=cc)
        {
            int now = pos[i];
            int fr = now - len[i];
            ll res;
           //    cout << fr << ' ' << now << ' '<<a.substr(fr,len[i])<<' '<<sum2[now] - sum2[fr+1]<<' '<<cnt[i]<<endl;
            res = sum2[now] - sum2[fr + cc-1];
            //res = max(res, (ll)0);
            ll num = cnt[i];
            res = (res%mm * num%mm) % mm;
            ans = (ans % mm + res % mm) % mm;
        }
    }
    printf("%lld\n", ans);
    return 0;
}
2020/8/12 12:55
加载中...