hdu5659 CA Loves Substring

Problem Description
CA loves strings, especially the substrings.
Now CA has a string S which consists of N digits. However, she split this string into two non-empty strings. Specifically, CA spilt the string into S1 and S2 two substrings at the middle of ith character and (i+1)th. Now, she wonders that there are how many non-empty strings are substring of S1 or S2 for each i.

Input
First line contains T denoting the number of testcases.
T testcases follow. Each testcase contains a integer in the first line, denoting N, the length of string S. The second line is a string whose length is N.
1≤T≤10, 2≤N≤200000

Output
For each testcase, you need output 1 line.
Let Fj represent the answer when i=j in this testcase, you need to output ∑N−1j=1Fj×100013N−j−1 mod (109+7)

Sample Input
2
2
00
4
0101

Sample Output
1
13300539

Hint
In the second case, when i=1 , S1 is “0”,S2 is “101”, All the Strings that satisfy the conditions are “0”,”1”,”10”,”01”,”101”.

Source
BestCoder Round #78 (div.1)

這是bc的好題啊.. 而且還是NanoApe出的啊..
附上題解,挺詳細的:
這裏寫圖片描述

表示在做這道題的時候一言不合把全部變量都變成了long long..

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define LL long long
using namespace std;
const LL Maxn = 200010;
const LL Mod = 1e9+7;
LL F[Maxn*2], d[Maxn*2], ch[Maxn*2][10], tot, now, G[Maxn*2];
char s[Maxn]; LL len;
LL mx[Maxn*2], mi[Maxn*2];
LL Rsort[Maxn*2], rk[Maxn*2];
void clear ( LL x ){ mx[x] = 0; mi[x] = len+1; memset ( ch[x], 0, sizeof (ch[x]) ); G[x] = 0; }
LL copy ( LL p, LL c ){
    LL x = ++tot, y = ch[p][c];
    d[x] = d[p]+1; clear (x);
    for ( LL i = 0; i < 10; i ++ ) ch[x][i] = ch[y][i];
    F[x] = F[y]; F[y] = x;
    while ( ~p && ch[p][c] == y ){ ch[p][c] = x; p = F[p]; }
    return x;
}
void add ( LL c ){
    LL p, o;
    if ( p = ch[now][c] ){
        if ( d[p] != d[now]+1 ) copy ( now, c );
        now = ch[now][c];
    }
    else {
        d[o=++tot] = d[now]+1; p = now; now = o; clear (o);
        while ( ~p && !ch[p][c] ){ ch[p][c] = o; p = F[p]; }
        F[o] = ~p ? ( d[p]+1 == d[ch[p][c]] ? ch[p][c] : copy ( p, c ) ) : 0;
    }
}
LL _max ( LL x, LL y ){ return x > y ? x : y; }
LL _min ( LL x, LL y ){ return x < y ? x : y; }
LL f[Maxn], g[Maxn], ans;
LL cf[Maxn];
int main (){
    LL i, j, k, T;
    scanf ( "%I64d", &T );
    cf[0] = 1;
    for ( i = 1; i <= 200000; i ++ ) cf[i] = ((LL)cf[i-1]*100013)%Mod;
    while ( T -- ){
        scanf ( "%I64d", &len );
        scanf ( "%s", s+1 );
        F[0] = -1; tot = now = 0; clear (0);
        for ( i = 1; i <= len; i ++ ){ add (s[i]-'0'); mx[now] = mi[now] = i; }
        memset ( Rsort, 0, sizeof (Rsort) );
        for ( i = 1; i <= tot; i ++ ){ Rsort[d[i]] ++; G[i] = 1; }
        for ( i = 1; i <= len; i ++ ) Rsort[i] += Rsort[i-1];
        for ( i = tot; i >= 1; i -- ) rk[Rsort[d[i]]--] = i;
        for ( i = tot; i >= 1; i -- ){
            mx[F[rk[i]]] = _max ( mx[rk[i]], mx[F[rk[i]]] );
            mi[F[rk[i]]] = _min ( mi[rk[i]], mi[F[rk[i]]] );
            for ( j = 0; j < 10; j ++ ){
                if ( ch[rk[i]][j] ) G[rk[i]] += G[ch[rk[i]][j]];
            }
        }
        for ( i = 0; i < 10; i ++ ){
            if ( ch[0][i] ) G[0] += G[ch[0][i]];
        }
        ans = G[0];
        memset ( f, 0, sizeof (f) );
        memset ( g, 0, sizeof (g) );
        for ( i = 1; i <= tot; i ++ ){
            LL l = d[F[i]]+1, r = d[i];
            l = _max ( l, mx[i]-mi[i]+1 );
            if ( l > r ) continue;
            g[mx[i]-r+1] ++;
            g[mx[i]-l+2] --;
            f[mi[i]] -= (r-l+1);
        }
        k = 0;
        for ( i = 1; i <= len; i ++ ){
            k = (k+g[i])%Mod;
            f[i] = (f[i]+k)%Mod;
        }
        for ( i = 1; i <= len; i ++ ) f[i] = (f[i]+f[i-1])%Mod;
        for ( i = 1; i < len; i ++ ) f[i] = ((ans-f[i])%Mod+Mod)%Mod;
        LL ssum = 0;
        for ( i = 1; i < len; i ++ ) ssum = (ssum+((LL)f[i]*cf[len-i-1])%Mod) % Mod;
        printf ( "%I64d\n", (ssum+Mod)%Mod );
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章