• 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
  • 相关阅读:
    批量SSH操作工具---OmniTTY安装
    CentOS6.6修改主机名和网络信息
    浪潮服务器通过ipmitool获取mac地址
    linux批量执行工具omnitty使用方法
    操作系统下查看HBA卡信息wwn的方法
    Linux下multipath多路径配置
    IPMITOOL 配置BMC用户设置
    第五讲 对于耦合的认识 target/action设计模式 delegate设计模式 手势识别器
    UI第四讲.事件处理(按钮点击切换视图,触摸事件)
    UI第三讲.自定义视图 视图控制器 检测屏幕旋转
  • 原文地址:https://www.cnblogs.com/ww3113306/p/10067368.html
Copyright © 2020-2023  润新知