1. 程式人生 > >2017 ACM-ICPC 亞洲區(西安賽區)網路賽 Barty's Computer(暴力+hash)

2017 ACM-ICPC 亞洲區(西安賽區)網路賽 Barty's Computer(暴力+hash)

Barty have a computer, it can do these two things.

  1. Add a new string to its memory, the length of this string is even.

  2. For given 44 strings a,b,c,da,b,c,d, find out how many strings that can be product by a+s1+b+c+s2+da+s1+b+c+s2+d, and |a| + |s1| + |b| = |c| + |s2| + |d|a+s1+b=c+s2+d

    |s|s means the length of string sss1s1 and s2s2 can be any string, including "".

Please help your computer to do these things.

Input Format

Test cases begins with T(T \le 5)T(T5).

Then TT test cases follows.

Each test case begins with an integer Q(Q \le 30000)Q(Q30000).

Then QQ lines,

1 s: add a new string s

s to its memory.

2 a b c d: find how many strings satisfying the requirement above.

\sum |s| + |a| + |b| + |c| + |d| \le 2000000s+a+b+c+d2000000.

Output Format

For type 22 query. Output the answer in one line.

樣例輸入

1
10
1 abcqaq
1 abcabcqaqqaq
2 ab bc qa aq
2 a c q q
1 abcabcqaqqwq
2 ab bc qa aq
2 a c q q
1 abcq
2 a c q q
2 a b c q

樣例輸出

1
2
1
3
3
1

解:因為題目沒有明確給出字串的個數與長度 所以這裡我們開一個長整型指標陣列避免越界

一開始逐個字元匹配T了 所以加了hash預處理

坑點 並不是文字串的總長度大於4個字串的總長度就可以 需要前兩個 和 後兩個字串的長度總和小於等於 文字串的一半

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <climits>
using namespace std;
const int N = 1e6+10;
typedef long long LL;
char str[N], a[N], b[N], c[N], d[N];
const LL mod = 1e9+7;
const LL seed = 1313;
LL *hash1[N], pos[N];
int xlen[N];

int main()
{
    pos[0]=1;
    for(int i=1;i<N;i++) pos[i]=pos[i-1]*seed%mod;
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        int h=0;
        while(n--)
        {
            int xx;
            scanf("%d", &xx);
            if(xx==1)
            {
                scanf("%s",str+1);
                int l=strlen(str+1);
                xlen[h]=l;
                hash1[h]=new LL[l+3];
                hash1[h][0]=0;
                for(int i=1;i<=l;i++)
                    hash1[h][i]=(hash1[h][i-1]*seed%mod+(str[i]-'a'+1))%mod;
                h++;
            }
            else
            {
                scanf("%s %s %s %s",a+1,b+1,c+1,d+1);
                int l1=strlen(a+1),l2=strlen(b+1),l3=strlen(c+1),l4=strlen(d+1);
                int sum=l1+l2+l3+l4, cnt=0;
                LL ans1=0, ans2=0, ans3=0, ans4=0;
                for(int j=1; j<=l1; j++) ans1=(ans1*seed%mod+(a[j]-'a'+1))%mod;
                for(int j=1; j<=l2; j++) ans2=(ans2*seed%mod+(b[j]-'a'+1))%mod;
                for(int j=1; j<=l3; j++) ans3=(ans3*seed%mod+(c[j]-'a'+1))%mod;
                for(int j=1; j<=l4; j++) ans4=(ans4*seed%mod+(d[j]-'a'+1))%mod;

                for(int i=0;i<h;i++)
                {
                    if((xlen[i]&1)||l1+l2>xlen[i]/2||l3+l4>xlen[i]/2) continue;
                    int cx=xlen[i]/2;
                    LL x=hash1[i][l1];
                    if(x!=ans1) continue;
                    x=(hash1[i][cx]-hash1[i][cx-l2]*pos[l2]%mod+mod)%mod;
                    if(x!=ans2) continue;
                    x=(hash1[i][cx+l3]-hash1[i][cx]*pos[l3]%mod+mod)%mod;
                    if(x!=ans3) continue;
                    x=(hash1[i][2*cx]-hash1[i][2*cx-l4]*pos[l4]%mod+mod)%mod;
                    if(x!=ans4) continue;
                    cnt++;
                }
                printf("%d\n",cnt);
            }
        }
    }
    return 0;
}