ZOJ 4030 JUMPin' JUMP UP!!!(字符串hash+思维)

 
JUMPin' JUMP UP!!!

Time Limit:1 Second      Memory Limit: 131072 KB
Tired of solving mathematical equations, DreamGrid starts to solve equations related to strings: for two strings and with the same length consisting of lowercase English letters, calculate , which is defined as the number of nonempty strings consisting of lowercase English letters such that and the length of does not exceed .

DreamGrid has two strings and . He would like to ask several questions about the value of , where is the substring of starting from with length and is a given number.

Input

There are multiple test cases. The first line of input contains an integer , indicating the number of test cases. For each test case:

The first line contains three integers and and () -- the length of , the length of and the number of questions.

The second line contains lowercase English letters denoting the string . The third line contains lowercase English letters denoting the string .

Each of the next lines contains two integers and () denoting the -th question.

It is guaranteed that neither the sum of all nor the sum of all exceeds .

Output

For each question, output an integer denoting the answer.

Sample Input

1
4 2 3
abcd
ba
1 2
2 2
3 2

Sample Output

 
 
1
0
0

       大致题意:给你两个字符串s和t。定义函数f(x,y,n)表示两个字符串x和y,构造一个长度小于n的串,使得最后xz=zy的z的个数。现在给出q个询问,每个询问一个x、一个y,让你求f(t,s[x]...s[x+len_t-1],y)的值。

        首先,我们考虑什么样的z可以满足条件。
                       
        对于上图的情况,因为xz=zy,所有t与z1相等,就有z1与z2相等,再有z2与s相等,最后又t=s。所以,在满足t=s的时候,要求z是t/s的整数倍复制。其实对于t与s不想等的时候,也是如此,看下图。

                   
        这种情况下,t1等于z,t2等于s1,z等于s2,可以推出t1=s2。那么s1=t2,s2=t1。这意味着s是t从某一个点截断之后,把截断部分补到t前面之后的字符串。此时z就是这个阶段点的位置。所以以上两种情况可以归结为,如果s是t在某一个点i截断再补到前面的串,那么方案数就是(n-i)/len+1。这里len就是s/t的长度。具体见下图,可行的z长度是2、6、10......

        但是,多找几个数据你会发现,对于有循环的单词来说,结果会比我们上面说的更多。我们还是用图来说明。
                                                           
        对于s为baba,t为abab的串,它的z的长度可以是1、3、5......可以看出这个递增规律并不是每次增加len,而是每次增加循环节的长度。因此,在这种情况下,答案就是(n-i)/loop+1,这里loop是最小循环节长度。

         最后,经过归纳,我们发现这两种情况可以统一,对于不循环的单词,我可以把他的循环节看作是整个串,即loop=len。这样结论就是(n-i)/loop+1,这个i就是最小拼接点。具体实现的话,可以考虑用字符串hash来解决,但是实现过程种发现数据卡hash,如果你使用ULL自动对2^64取模,那么很遗憾会被卡掉。只有当利用两个质数hash的时候才能够AC。具体见代码:

#include<bits/stdc++.h>
#define LL long long
#define N 200010
using namespace std;

struct String_Hash
{
    LL Hs[N],hs[N],p[N],P[N];
    const LL mod=100001651,MOD=100001623;

    void ins(char *s)
    {
        p[0]=P[0]=1;
        Hs[0]=hs[0]=s[0]-'a'+1;
        for(int i=1;s[i];i++)
        {
            Hs[i]=(Hs[i-1]*111%MOD+s[i]-'a'+1)%MOD;
            hs[i]=(hs[i-1]*100007%mod+s[i]-'a'+1)%mod;
            P[i]=P[i-1]*111%MOD;p[i]=p[i-1]*100007%mod;
        }
    }

    pair<LL,LL> Hash(int l,int r)
    {
        LL tmp1=Hs[r],tmp2=hs[r];
        if (!l) return make_pair(tmp1,tmp2);
        tmp1=(tmp1-Hs[l-1]*P[r-l+1]%MOD+MOD)%MOD;
        tmp2=(tmp2-hs[l-1]*p[r-l+1]%mod+mod)%mod;
        return make_pair(tmp1,tmp2);
    }

} S,T;

map< pair<LL,LL>, int > mp;
char s[N],t[N];
int Next[N],m;

void getNext()
{
    Next[0]=-1;
    for (int i=1;i<=m;i++)
    {
        int p=Next[i-1];
        while (p>=0 && t[p+1]!=t[i]) p=Next[p];
        Next[i]=p+1;
    }
}

int main()
{
    int T_T;
    scanf("%d",&T_T);
    while(T_T--)
    {
        int n,q;LL loop;
        scanf("%d%d%d%s%s",&n,&m,&q,s+1,t+1);
        getNext(); loop=m-Next[m];
        if (Next[m]*2<m) loop=m;
        for(int i=m+1;i<=2*m;i++) t[i]=t[i-m];
        S.ins(s+1); T.ins(t+1); mp.clear();
        for(int i=0;i<m;i++)
        {
            pair<LL,LL> tmp;
            tmp=T.Hash(m-i,2*m-i-1);
            mp[tmp]=m-i;
        }
        while(q--)
        {
            int k; LL len,tp;
            scanf("%d%lld",&k,&len);
            pair<LL,LL> tmp;
            tmp=S.Hash(k-1,k+m-2);
            if (mp[tmp])
            {
                tp=mp[tmp];
                if (len>=tp) printf("%lld\n",(len-tp)/loop+1LL);
                        else puts("0");
            } else puts("0");
        }
    }
    return 0;
}

 
 


猜你喜欢

转载自blog.csdn.net/u013534123/article/details/80231840
ZOJ