1 条题解

  • 0
    @ 2025-8-24 22:04:19

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar hovny
    <vSiLenCe^>

    搬运于2025-08-24 22:04:19,当前版本为作者最后更新于2018-12-26 14:24:09,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    Update 2019.11.08\mathtt{Update\ 2019.11.08}

    题面

    在字符串 AA 中,如果字符串 BBAA 的子串,那么就删除在 AA 中第一个出现的 BB,然后拼接在一起,一直重复上述步骤直到 BB 不再是 AA 的子串

    |A|106\le 10^6

    解题思路

    KMP+栈

    分析

    1、字符串匹配的问题,想到 KMPKMP

    2、在匹配过程中,如果匹配成功了,就将子串 BB 删除,可以证明,对之前不会产生影响

    3、删了再加入,类似栈的操作,因此用栈维护上述操作过程中的字串即可

    过程

    1、KMPKMP 板子跑一遍

    2、在 KMPKMP 过程中,把遍历到的 ii(不是字符,而是下标)入栈,当匹配上 BB 时,就把匹配的部分出栈,然后 jj 从栈顶的 ii 所能匹配到的最大的位置开始(就是 f[i] 记录的值),继续做 KMPKMP

    时间复杂度:BB 自身匹配一次 +A+ABB 匹配一次+A+A 中最多每个字符进出栈一次,为 O(A)O(|A|)

    Code

    #include<bits/stdc++.h>
    #define N 1000010
    using namespace std;
    int la,lb,res;
    char a[N],b[N];
    int p[N],f[N];//分别表示B串自身匹配的结果、A串与B串匹配的结果
    int St[N],top;
    int main()
    {
    	int i,j;
    	scanf("%s",a+1);
    	scanf("%s",b+1);
    	la=strlen(a+1);
    	lb=strlen(b+1);
    	for(i=2,j=0;i<=lb;i++) {//自身匹配
    		while(j&&b[i]!=b[j+1])
    			j=p[j];
    		if(b[i]==b[j+1])
    			j++;
    		p[i]=j;
    	}
    	for(i=1,j=0;i<=la;i++) {//A与B匹配
    		while(j&&a[i]!=b[j+1])
    			j=p[j];
    		if(a[i]==b[j+1])
    			j++;
    		f[i]=j;//记录结果
    		St[++top]=i;//入栈
    		if(j==lb)//如果匹配成功,弹出,并更新j值
    			top-=lb,j=f[St[top]];
    	}
    	for(i=1;i<=top;i++)//大功率输出
    		printf("%c",a[St[i]]);
    	return 0;
    }
    

    再扔道题 Luogu P3121 [USACO15FEB]审查(黄金)Censoring (Gold)

    • 1

    信息

    ID
    3850
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者