zoukankan      html  css  js  c++  java
  • CF1200E 题解

    这题从头到脚都散发着均摊(暴力)的气息 qwq


    题意就是输入很多 ((leq 10^5))串, 维护一个 (ans) 串, 起始时 (ans) 串为空, 每输入一个串就要和 (ans) 串合并, 合并时将输入的串的最长的和 (ans) 串的某一后缀相等的前缀去掉, 然后把剩下部分接到 (ans) 串的后面。
    输入串的总长不超过 (10^6)


    如果每次都暴力地将整个 (ans) 串和输入串用 (kmp) 合并, 复杂度就成了 (O(可以被卡))
    但是如果注意到去掉的输入串的前缀长度不会超过输入串的总长, 每次只截取 (ans) 的一段长为输入串长度的后缀与输入串暴力合并, 复杂度就成了均摊 (O(输入串总长)),似乎快的一批。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 2e6 + 15;
    
    int n, ansl;
    char s[maxn], ans[maxn], tmp[maxn];
    int nxt[maxn];
    int main()
    {
    	cin>>n;
    	scanf("%s", ans+1);
    	ansl = strlen(ans+1);
    	--n;
    	while(n--) {
    		scanf("%s", s+1);
    		int sl = strlen(s+1);
    		int tmpl = min(sl,ansl);
    		for(int i=1;i<=tmpl;++i) tmp[i] = s[i];
    		for(int i=1;i<=tmpl;++i) tmp[tmpl+i] = ans[ansl-tmpl+i];
    		tmpl<<=1;
    		nxt[1]=0;
    		for(int i=2,j=0;i<=tmpl;++i) {
    			while(j&&tmp[j+1]!=tmp[i]) j=nxt[j];
    			if(tmp[j+1]==tmp[i]) ++j;
    			nxt[i]=j;
    		}
    		int mxpl = nxt[tmpl];
    		while(mxpl>tmpl/2) mxpl = nxt[mxpl];
    		int deltal = sl-mxpl;
    		for(int i=1;i<=deltal;++i) ans[ansl+i] = s[mxpl+i];
    		ansl += deltal;
    	}
    	for(int i=1;i<=ansl;++i) putchar(ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    lesson
    lesson
    课后习题-5
    lesson
    lesson
    lesson
    重启网络服务时 Bringing up interface eth0
    课后习题-4
    基础扩展
    课后习题-3
  • 原文地址:https://www.cnblogs.com/tztqwq/p/12799672.html
Copyright © 2011-2022 走看看