zoukankan      html  css  js  c++  java
  • 【做题】BZOJ2342 双倍回文——马拉车&并查集

    题意:有一个长度为(n)的字符串,求它最长的子串(s)满足(s)是长度为4的倍数的回文串,且它的前半部分和后半部分都是回文串。

    (n leq 5 imes 10^5)

    首先,显然要用manacher求出以每一位为中心的最长回文串。考虑枚举(s)最中间的一个位置(i),且以其为中心的最长回文串长度为(2 r_i),那么,前半部分的中心(j)就必须在([i - lfloor frac {r_i} {2} floor,i))的区间上,并且(i - j leq r_j)。当然,我们会贪心地选择这个区间上最左边的合法的(j)。并且,只要某个(j)在当前中心为(i)的时候满足(i - j leq r_j),那么,对于所有(k leq i),都有(k - j leq r_j)

    于是,只要从左往右移动(i),每次删除移动后非法的(j),问题就变成实现一个数据结构,支持:

    • 删除一个元素
    • 求一个值后继

    这可以轻易地以(O(n log n))的时间复杂度实现,但我们希望一个更优的算法。

    考虑一个元素如果每删除了,那么受影响的就只有以它为后继的值。这些值的后继会变成它们后继的后继。设(S_i)表示以元素(i)为后继的所有值的集合,那么,删除(i)后,我们只要把(S_i)合并到(S_j)里面就可以了。(元素(j)是元素(i)的后继)

    因此,我们用并查集维护一下就好了。这个巧妙的技巧应该会在本题卡常时发挥作用。

    时间复杂度(O(n alpha(n)))

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 500010;
    int n,len[N * 2],r[N];
    char s[N];
    void manacher() {
      for (int i = 2 ; i <= (n << 1) ; ++ i) {
        int l = i >> 1, r = (i + 1) >> 1;
        while (s[l - len[i]] == s[r + len[i]] && l - len[i] >= 1 && r + len[i] <= n)
          ++ len[i];
        l = i - 1, r = i + 1;
        while ((l >> 1) - len[l] > (i >> 1) - len[i] && l >= 1 && r <= 2 * n)
          len[r++] = len[l--];
        len[r] = ((i + 1) >> 1) + len[i] - ((r + 1) >> 1);
        i = r - 1;
      }
    }
    int uni[N],ans;
    vector<int> vec[N];
    int getfa(int pos) {
      return pos == uni[pos] ? pos : uni[pos] = getfa(uni[pos]);
    }
    int main() {
      scanf("%d",&n);
      scanf("%s",s+1);
      manacher();
      for (int i = 1 ; i <= n ; ++ i)
        r[i] = len[i << 1 | 1];
      for (int i = 1 ; i <= n ; ++ i)
        uni[i] = i;
      for (int i = 1 ; i < n ; ++ i) {
        int k = i - (r[i] >> 1);
        ans = max(ans,4 * (i - getfa(k)));
        vec[i + r[i]].push_back(i);
        for (int j = 0 ; j < (int)vec[i].size() ; ++ j)
          uni[vec[i][j]] = vec[i][j] + 1;
      }
      printf("%d
    ",ans);
      return 0;
    }
    

    小结:对一些简单的小技巧还是不熟悉。或许是平庸的大数据结构做多了的问题吧。做题策略要调整。

  • 相关阅读:
    git .gitignore re-include
    excel 排名次
    ssh agent and ssh add for git Permission denied
    Git 仓库 清理 瘦身
    EF Core ThenInclude 2.0自动完成提示有误,坑了一下
    Entity Framework Core 导航属性 加载数据
    .net core mvc 模型绑定 之 json and urlencoded
    HttpClientHelper
    提示错误:“应为“providerInvariantName”参数的非空字符串。”
    关于.NET WebAPI 常见的跨域问题 解决清单
  • 原文地址:https://www.cnblogs.com/cly-none/p/9379566.html
Copyright © 2011-2022 走看看