zoukankan      html  css  js  c++  java
  • 2017 Multi-University Training Contest

    Classic Quotation

    Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)

    Problem Description
    When online chatting, we can save what somebody said to form his ''Classic Quotation''. Little Q does this, too. What's more? He even changes the original words. Formally, we can assume what somebody said as a string S whose length is n. He will choose a continuous substring of S(or choose nothing), and remove it, then merge the remain parts into a complete one without changing order, marked as S. For example, he might remove ''not'' from the string ''I am not SB.'', so that the new string S will be ''I am SB.'', which makes it funnier.



    After doing lots of such things, Little Q finds out that string T occurs as a continuous substring of S very often.

    Now given strings S and T, Little Q has k questions. Each question is, given L and R, Little Q will remove a substring so that the remain parts are S[1..i] and S[j..n], what is the expected times that T occurs as a continuous substring of S if he choose every possible pair of (i,j)(1iL,Rjn) equiprobably? Your task is to find the answer E, and report E×L×(nR+1) to him.

    Note : When counting occurrences, T can overlap with each other.
     
    Input
    The first line of the input contains an integer C(1C15), denoting the number of test cases.

    In each test case, there are 3 integers n,m,k(1n50000,1m100,1k50000) in the first line, denoting the length of S, the length of T and the number of questions.

    In the next line, there is a string S consists of n lower-case English letters.

    Then in the next line, there is a string T consists of m lower-case English letters.

    In the following k lines, there are 2 integers L,R(1L<Rn) in each line, denoting a question.
     
    Output
    For each question, print a single line containing an integer, denoting the answer.
     
    Sample Input
    1 8 5 4 iamnotsb iamsb 4 7 3 7 3 8 2 7
     
    Sample Output
    1 1 0 0
     分析:首先,对于某一对(l,r),我们可以求出答案为preg l + suf r,pref l;
       其中preg表示前缀l中T的个数,pref l表示匹配完前缀l指针所在位置,suf r,pref l表示从r开始的后缀中从pref l指针开始匹配得到的T的个数;
       因为要求所有的贡献和,l<=L,r>=R,所以考虑前缀和与后缀和;
       ans=i=1​~L​​j=R~n​ ​pregi​​ sufj,prefi​​​​=(nR+1)pregL​​+i=0~m1​​ sL,i​​×sufR,i​​
    代码:
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <cstring>
    #include <string>
    #include <set>
    #include <bitset>
    #include <map>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cassert>
    #include <ctime>
    #define rep(i,m,n) for(i=m;i<=(int)n;i++)
    #define mod 998244353
    #define inf 0x3f3f3f3f
    #define vi vector<int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define pi acos(-1.0)
    #define pii pair<int,int>
    #define sys system("pause")
    #define ls rt<<1
    #define rs rt<<1|1
    #define all(x) x.begin(),x.end()
    const int maxn=5e4+10;
    const int N=5e4+10;
    using namespace std;
    ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
    ll qmul(ll p,ll q,ll mo){ll f=0;while(q){if(q&1)f=(f+p)%mo;p=(p+p)%mo;q>>=1;}return f;}
    ll qpow(ll p,ll q,ll mo){ll f=1;while(q){if(q&1)f=qmul(f,p,mo)%mo;p=qmul(p,p,mo)%mo;q>>=1;}return f;}
    int n,m,k,t,nxt[maxn],nxt1[110][26];
    ll pref[maxn],preg[maxn],s[maxn][110],suf[maxn][110];
    char a[maxn],b[maxn];
    void init(char *a,char *b)
    {
        for(int i=0;i<=n;i++)
        {
            pref[i]=preg[i]=0;
            for(int j=0;j<=m;j++)
            {
                s[i][j]=suf[i][j]=0;
            }
        }
        nxt[0]=-1;
        int j=-1;
        for(int i=0;i<=m;i++)
        {
            while(!(j==-1||b[j]==b[i]))j=nxt[j];
            nxt[i+1]=++j;
        }
        j=0;
        for(int i=0;i<n;i++)
        {
            while(!(j==-1||a[i]==b[j]))j=nxt[j];
            if(i)preg[i]=preg[i-1];
            pref[i]=++j;
            s[i][j]++;
            if(j==m)preg[i]++;
        }
        for(int i=1;i<n;i++)
        {
            preg[i]+=preg[i-1];
            for(int j=0;j<=m;j++)
            {
                s[i][j]+=s[i-1][j];
            }
        }
        for(int i=0;i<=m;i++)
        {
            for(int j='a';j<='z';j++)
            {
                int k=i;
                while(!(k==-1||j==b[k]))k=nxt[k];
                nxt1[i][j-'a']=k+1;
            }
        }
        for(int i=n-1;i>=0;i--)
        {
            for(int j=0;j<=m;j++)
            {
                int tmp=nxt1[j][a[i]-'a'];
                suf[i][j]+=suf[i+1][tmp];
                if(tmp==m)suf[i][j]++;
            }
        }
        for(int i=n-1;i>=0;i--)
        {
            for(int j=0;j<=m;j++)
            {
                suf[i][j]+=suf[i+1][j];
            }
        }
    }
    int main()
    {
        int i,j;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d",&n,&m,&k);
            scanf("%s%s",a,b);
            init(a,b);
            while(k--)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                ll ret=(n-y+1)*preg[x-1];
                for(int i=0;i<=m;i++)
                {
                    ret+=s[x-1][i]*suf[y-1][i];
                }
                printf("%lld
    ",ret);
            }
        }
        return 0;
    }
  • 相关阅读:
    【leetcode】Partition List
    【USACO】Transformations
    【USACO】Milking Cows
    R语言学习笔记——Base Graphics
    【Tech】YCSB-0.1.3安装使用
    【Tech】Ganglia安装配置
    【leetcode刷题笔记】Remove Duplicates from Sorted List
    【leetcode】Populating Next Right Pointers in Each Node
    【leetcode刷题笔记】Spiral Matrix
    js中定时器的使用
  • 原文地址:https://www.cnblogs.com/dyzll/p/7295071.html
Copyright © 2011-2022 走看看