首页 > 其他分享 >P3893 [GDOI2014] Beyond 题解

P3893 [GDOI2014] Beyond 题解

时间:2023-12-23 16:23:51浏览次数:29  
标签:LCP P3893 题解 int text GDOI2014 sim

P3893 [GDOI2014] Beyond 题解

思路

称第一个字符串为 \(A\),第二个字符串 \(B\)。

考虑枚举环长 \(L\),那么如果 \(L\) 是可行的,当且仅当存在一个位置 \(i\),使得 \(A_{1\sim i} = B_{L - i + 1, L}, A_{i + 1\sim L} = B_{1, L - i}\),也就是 \(A_{1\sim L}\) 的一个前缀和 \(B_{1\sim L}\) 的一个后缀匹配,且此处 \(A_{1\sim L}\) 的后缀与 \(B_{1\sim L}\) 的前缀匹配。

固定 \(L\) 之后可以暴力去寻找 \(i\),但是之后这个方向就很难突破了,所以考虑固定 \(i\),寻找最长的 \(L\),如果设 \(j = L - i\),就转化为寻找最大合法的 \(j\),发现这个形式很像 ExKMP,则如果求出了 \(l = \text{LCP}(A_{1\sim i}, B)\),那么对于所有 \(j\in_{1, l}\),\(A_{i + 1, i + j} = B_{1\sim j}\),而对于更大的 \(j\),都是不合法的。

但是当 \(j = l\) 的时候,有可能没法满足第一个约束,即 \(A_{1\sim i} = B_{j + 1, i + j}\),所以朴素的做法是枚举所有的 \(j\),然后判断 \(\text{LCP}(B_{j + 1, i + j}, A) \ge i\),如果满足这个条件,就可以缩短最长公共前缀来找到一个刚好满足条件的位置。

为了优化做法,用式子表示出来:

\[\max_{i = 1}^n\max_{1\le j\le LCP(A_{1\sim i}, B)\wedge LCP(B_{j + 1, i + j}, A) \ge i}(i + j) \]

发现底下的式子是二维偏序,所以可以用树状数组解决这个问题。

具体而言,从大到小枚举 \(i\),每次把所以满足 \(\text{LCP}(B_{j + 1, i + j}, A) \ge i\) 的 \(j\) 加入树状数组中,然后每次查询:

\[i + \max_{1\le j\le LCP(A_{1\sim i}, B)}j \]

这样就是前缀 \(\max\),也就可以用树状数组维护。

上述 \(\text{LCP}\) 的值都可以通过 ExKMP 求得。

时间复杂度:\(O(n\log n)\)。

// Problem: P3893 [GDOI2014] Beyond
// Contest: Luogu
// Author: Moyou
// Copyright (c) 2023 Moyou All rights reserved.
// Date: 2023-12-21 23:25:40

#include <cstring>
#include <iostream>
using namespace std;
const int N = 2e6 + 10, M = 2e6 + 10;

int n;
int z1[N], z2[N], exz1[N], exz2[N];
string a, b;
void Z(string s, int z[]) {
    z[1] = s.size();
    for(int i = 2, l = 0, r = 0; i < s.size(); i ++) {
        if(i <= r) z[i] = min(z[i - l + 1], r - i + 1);
        while(i + z[i] < s.size() && s[i + z[i]] == s[z[i] + 1]) z[i] ++;
        if(i + z[i] - 1 > r) l = i, r = i + z[i] - 1;
    }
}
void exkmp(string a, string b, int z[], int p[]) {
    Z(a, z);
    for(int i = 1, l = 0, r = 0; i < b.size(); i ++) {
        if(i <= r) p[i] = min(z[i - l + 1], r - i + 1);
        while(p[i] + 1 < a.size() && i + p[i] < b.size() && a[p[i] + 1] == b[i + p[i]]) p[i] ++;
        if(i + p[i] - 1 > r) l = i, r = i + p[i] - 1;
    }
}
struct BIT {
    int tr[N];
    void update(int i, int c)  { for (; i <= n; i += i & -i) tr[i] = max(c, tr[i]); }
    int query(int i)  { int res = -1e9; for (; i; i &= i - 1) res = max(res, tr[i]); return res; }
    void clear() {memset(tr, -0x3f, sizeof tr);}
} bit;
int h[N], ne[M], e[M], idx;
void add(int a, int b) {
	e[idx] = b, ne[idx] = h[a], h[a] = idx++; 
}
signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> a >> b;
    a = "$" + a, b = "$" + b;
    exkmp(a, b, z1, exz1);
    exkmp(b, a, z2, exz2);
    int ans = 0;
    memset(h, -1, sizeof h);
    for(int i = 1; i <= n; i ++)
        add(exz1[i + 1], i);
    bit.clear();
    for(int i = n; i; i --) {
        for(int j = h[i]; ~j; j = ne[j])
            bit.update(e[j], e[j]);
        ans = max(ans, i + bit.query(exz2[i + 1]));
    }
    cout << ans << '\n';

    return 0;
}

标签:LCP,P3893,题解,int,text,GDOI2014,sim
From: https://www.cnblogs.com/MoyouSayuki/p/17923234.html

相关文章

  • 【洛谷 P1781】宇宙总统 题解(高精度+结构体排序)
    宇宙总统题目描述地球历公元6036年,全宇宙准备竞选一个最贤能的人当总统,共有个非凡拔尖的人竞选总统,现在票数已经统计完毕,请你算出谁能够当上总统。输入格式第一行为一个整数,代表竞选总统的人数。接下来有行,分别为第一个候选人到第个候选人的票数。输出格式共两行,第一行是......
  • 题解:【XR-3】核心城市
    题解:【XR-3】核心城市思路一:考虑由特例推广到一般1、很容易想到先考虑一个关键点的情况,然后再推广到一般情况。2、一个点肯定选距离上最平衡的那个点,即树的中心。接着在中心周围贪心的选剩下的(k-1)个关键点即可。3、这里有一个误区:各点到某点的距离最小,是找树的中心而不是重......
  • 闭合区域面积统计 题解
    题目描述计算一个\(10\times10\)矩阵中由\(1\)围成的图形的面积。如下所示,在\(10\times10\)的二维数组中,\(1\)围住了\(15\)个点,因此面积为\(15\)。000000000000001110000000100100000001001000100010100101......
  • CF1881F Minimum Maximum Distance 题解
    因为白点对\(f_i\)没有贡献,所以可以重构出一棵原树的子树,使得所有的叶子都为标记点且标记点数量不变(没有删去标记点)。因为没有标记被删去且结构不变,所以这棵树的答案与原树答案相同。现在,对于所有节点,到它距离最大的标记点一定在叶子上。那么问题就变为:求出树上任意一点到所有......
  • ISCTF2023部分题解
    WEB:圣杯战争!!!(题解:结局别说遗憾Zn.)解题思路:打开题目链接,代码如下:<?phphighlight_file(__FILE__);error_reporting(0);classartifact{public$excalibuer;public$arrow;publicfunction__toString(){echo"为Saber选择了对的武器!<br>";return$this->excal......
  • 【洛谷 P1093】[NOIP2007 普及组] 奖学金 题解(结构体排序)
    [NOIP2007普及组]奖学金题目描述某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前名学生发奖学金。期末,每个学生都有门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规......
  • [CF17E] Palisection 题解
    [CF17E]Palisection题解思路直接统计相交的字符串很难数,考虑正难则反。用总共的回文串对数减去相离的回文串个数。设总共有\(tot\)个回文串,用manacher跑出来每个位置的最大回文半径后,使用差分的技巧保存两个数组:\(f_i\)表示以\(i\)为开头的回文串个数,\(g_i\)表示以......
  • CF187A 题解
    原题传送门题目大意如题意翻译。思路分析很水的一道题目,可以将第一个排列\(a\)看作最终排列,接下来每输入一个数,让它与\(a_m\)进行比较,直到两个排列相同。最后看题目范围,\(1≤n≤2\times10^5\),时间复杂度\(\mathcal{O(n)}\),空间复杂度\(\mathcal{O(n)}\)。代码:/*Writ......
  • CF1912L 题解
    原题传送门题目大意有一个仅有0和L构成的序列,求出一种方案,使得左部分的0数量不等于右部分的O数量,且左部分的L数量不等于右部分的L数量,若不存在输出-1。思路分析首先看题目范围,\(2≤n≤200\),数据很小,考虑暴力。可以使用字符串截取函数s.substr()。本题我们使......
  • P5289 [十二省联考 2019] 皮配 题解
    题目链接点击打开链接题目解法题意比较复杂,形式化一下题意是:一些人和一些城市,每个人属于一个城市,每个人属于\(A/B/C/D\)队,需要满足:每个城市中的人要么都属于\(AC\)或\(BD\),且\(A+C\leC_0,\;B+D\leC_1,\;A+B\leD_0,\;C+D\leD_1\)暴力\(dp\)是\(f_{i,a,b,c}\)表......