Queries on a String (字符串子顺序)

原题:Gym - 101755L

题意:

有个案例字符串和空字符串,有q个对第二个字符串的操作,push一个字母或是pop一个,问操作之后的字符串是不是案例字符串的子顺序串

解析:

开始的时候我对每个字母x找到下一次x出现的位置,结果T了,改进了一下

对每一个位置找出所有26个字母下次出现位置

代码:


D read(){ D ans=0; char last=' ',ch=getchar();
while(ch<'0' || ch>'9')last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}

const int N=200009;

string x;
int pre[27];
int nex[N][27];
stack<int>s;
int now=-1;
int yv=0;

void push(char t){int p=t-'a';
    if(yv)yv++,printf("NO\n");
    else if(now==-1){
        if(pre[p]==-1)yv++,printf("NO\n");
        else now=pre[p],s.push(now),printf("YES\n");
    }
    else{
        if(nex[now][p]==-1)yv++,printf("NO\n");
        else now=nex[now][p],s.push(now),printf("YES\n");
    }
}

void pop(){
    if(yv){
        yv--;if(yv)printf("NO\n");
        else printf("YES\n");
    }
    else{
        printf("YES\n");
        s.pop();
        if(s.empty())now=-1;
        else now=s.top();
    }
}

int main(){
    cin>>x;
    mmm(pre,-1);
    for(int i=x.length()-1;i>=0;i--){
        for(int j=0;j<26;j++)nex[i][j]=pre[j];
        pre[x[i]-'a']=i;
    }
    int q=read();
    while(q--){
        char tmp[5];scanf("%s",tmp);
        if(tmp[1]=='u')scanf("%s",tmp),push(tmp[0]);
        else pop();
    }
}

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/81225214