先给出一个s母串

然后给出n个子串

判断是否为母串的子序列

 

3000ms  2993ms过的。。。。

蒻鲫的代码:

建立表格 二分  加一个小剪枝。。

M. Subsequence  南昌邀请赛_#includeM. Subsequence  南昌邀请赛_#include_02
#include<bits/stdc++.h>
using namespace std;
//input b y bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
#define inf 0x3f3f3f3f
//////////////////////////////////
char s[100000+6];
char p[1000+5];
int list1[500][100000+5];
int num[500];
int lens;

bool judge(char p[])
{
    int now=-1;
    int lenp=strlen(p);
    rep(i,0,lenp-1)
    {
        int id=p[i];
        if(num[id]==0)return false;

        int pos=lower_bound( list1[id]+1,list1[id]+1+num[id],now)-list1[id];
        if( list1[id][pos]>=now&&pos<=num[id] )
        {
            if( lenp-i>=lens-now   )return false;
            now=list1[id][pos]+1;
        }
        else return false;
    }
    return 1;

}

int main()
{
    RS(s);
    int n;
    RI(n);
    lens=strlen(s);
    rep(i,0,lens-1)
    {
        list1[s[i]][ ++num[s[i]] ]=i;
    }


    while(n--)
    {
        RS(p);
        if(judge(p))puts("YES");
        else puts("NO");


    }


    return 0;
}
View Code

 

大神的做法:

1000ms

建立邻接矩阵直接跳就行了

M. Subsequence  南昌邀请赛_#includeM. Subsequence  南昌邀请赛_#include_02
#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
#include <queue>
#include <stack>
#include <functional>
#include <map>
#include <set>
#include <bitset>
#include <ctime>
#include <complex>

#define INF 0x3f3f3f3f
#define memset0(x) memset(x, 0, sizeof(x))
#define memsetM1(x) memset(x, -1, sizeof(x))
#define memsetINF(x) memset(x, INF, sizeof(x))

using namespace std;

const int MAXN = 1e5 + 5;
char str[MAXN];
int nxt[MAXN][26];
char str2[MAXN];
int lst[26];

int main()
{
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
    int startTime = clock();
#endif
    scanf("%s", str + 1);
    int n = strlen(str + 1);
    for (int i = 1; i <= n; i++)
    {
        int id = str[i] - 'a';
        for (int j = i - 1; j >= lst[id]; j--)
        {
            nxt[j][id] = i;
        }
        lst[id] = i;
    }
    int t;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%s", str2);
        int loc = 0;
        bool yes = true;
        for (int i = 0; str2[i]; i++)
        {
            int id = str2[i] - 'a';
            if (nxt[loc][id])
            {
                loc = nxt[loc][id];
            }
            else
            {
                yes = false;
                break;
            }
        }
        if (yes)
        {
            puts("YES");
        }
        else
        {
            puts("NO");
        }
    }

#ifndef ONLINE_JUDGE
    printf("Time = %dms\n", clock() - startTime);
#endif
    return 0;
}
View Code