zoukankan      html  css  js  c++  java
  • CF17E Palisection manacher

    题面:洛谷(带翻译)

    题解:

      直接求相交不太好求,所以考虑求不相交的回文串对数。

      设ll[i]表示以i为开头的回文串个数,rr[i]表示结尾<=i的回文串个数。

      然后不相交的回文串对数显然就是对于每个$rr[i - 1] cdot ll[i]$求一次和。

      最后再用全集减去不相交的回文串对数即可求出相交的回文串对数。

      那么如何求这2个数组呢?

        对于每个最长回文半径r[i],它可以对一个区间做出贡献,即以它为中心那些回文串的开头or结尾都在一个区间内,相当于每个r[i]都可以对某个区间做区间加。

        因此我们差分维护一下可以得到ll数组,同理也可以得到表示以i为结尾的回文串个数的数组,然后对这个数组求一次前缀和即可得到rr数组

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define R register int
     4 #define AC 2010000
     5 #define ac 4001000
     6 #define LL long long
     7 #define p 51123987
     8 
     9 int n, maxn, pos, len;
    10 int r[ac];
    11 LL ll[AC], rr[AC];
    12 LL sum;
    13 char ss[AC], s[ac];
    14 
    15 void pre()
    16 {
    17     scanf("%d%s", &len, ss + 1);
    18     s[0] = '$', s[1] = '#', n = (len << 1) | 1;
    19     for(R i = 1; i <= len; i ++) s[i << 1] = ss[i], s[(i << 1) | 1] = '#';
    20 }
    21 
    22 void manacher()
    23 {
    24     for(R i = 1; i <= n; i ++)
    25     {
    26         r[i] = (maxn > i) ? min(r[(pos << 1) - i], maxn - i + 1) : 1;
    27         while(s[i + r[i]] == s[i - r[i]]) ++ r[i];
    28         if(i + r[i] - 1 > maxn) maxn = i + r[i] - 1, pos = i;
    29         ++ rr[(i + 1) >> 1], -- rr[(i + r[i]) >> 1];
    30         ++ ll[(i  - r[i] + 1 + 1) >> 1], -- ll[(i >> 1) + 1];
    31     }
    32     for(R i = 1; i <= len; i ++) 
    33         rr[i] = (rr[i] + rr[i - 1]) % p, ll[i] = (ll[i] + ll[i - 1]) % p;
    34     for(R i = 1; i <= len; i ++) rr[i] = (rr[i] + rr[i - 1]) % p;//统计一次前缀和
    35 }
    36 
    37 void work()
    38 {
    39     sum = rr[len] * (rr[len] - 1) / 2 % p;
    40     for(R i = 2; i <= len; i ++)
    41         sum = (sum - rr[i - 1] * ll[i] % p + p) % p;
    42     printf("%lld
    ", (sum + p) % p);
    43 }
    44 
    45 int main()
    46 {
    47 //    freopen("in.in", "r", stdin);
    48     pre();
    49     manacher();
    50     work();
    51 //    fclose(stdin);
    52     return 0;
    53 }
    View Code
  • 相关阅读:
    如何编写优雅的代码:05. 设计模式(下)
    ArcGIS之Cartogram地图变形记
    GIS规划应用——基于哈夫模型的GIS服务区分析
    基于GIS的旅游辐射区人口统计
    图斑整理之字段计算器使用技巧
    ArcGIS制作放射状流向地图(Radial Flow Map)
    SQL Server时间粒度系列
    (原)SQL Server 代理作业执行持续时间简述
    (原)SQL Server 系统提供功能的三个疑惑
    sql server实现自定义分割月功能
  • 原文地址:https://www.cnblogs.com/ww3113306/p/10067368.html
Copyright © 2011-2022 走看看