• CF17E Palisection


    嘟嘟嘟

    题中让求相交的回文串的对数,不太好求。不过求不相交的回文串对数就简单多了。

    因为对于一位 i,在这一位不相交的回文串对数numi = 以这一位结束的回文串个数 ×在这一位后面开始的回文串个数。用manacher跑一遍 + 差分,然后维护一个开始的回文串的后缀和就好了。

    然后统计回文串个数sum,那么ans = sum * (sum - 1) / 2 - ∑numi

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 typedef long long ll;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const db eps = 1e-8;
    20 const int mod = 51123987;
    21 const int maxn = 2e6 + 5;
    22 inline ll read()
    23 {
    24     ll ans = 0;
    25     char ch = getchar(), last = ' ';
    26     while(!isdigit(ch)) {last = ch; ch = getchar();}
    27     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
    28     if(last == '-') ans = -ans;
    29     return ans;
    30 }
    31 inline void write(ll x)
    32 {
    33     if(x < 0) x = -x, putchar('-');
    34     if(x >= 10) write(x / 10);
    35     putchar(x % 10 + '0');
    36 }
    37 
    38 int n;
    39 char s[maxn], t[maxn << 1];
    40 int p[maxn << 1];
    41 int enn[maxn << 1], beg[maxn << 1];
    42 
    43 void init()
    44 {
    45   t[0] = '@';
    46   for(int i = 0; i < n; ++i) t[i << 1 | 1] = '#', t[(i << 1) + 2] = s[i];
    47   n = (n << 1) + 2;
    48   t[n - 1] = '#'; t[n] = '$';
    49 }
    50 void manacher()
    51 {
    52   int mx = 0, id;
    53   for(int i = 1; i < n; ++i)
    54     {
    55       if(mx > i) p[i] = min(p[(id << 1) - i], mx - i);
    56       else p[i] = 1;
    57       while(t[i - p[i]] == t[i + p[i]]) p[i]++;
    58       if(i + p[i] > mx) mx = p[i] + i, id = i;
    59     }
    60 }
    61 
    62 ll ans = 0;
    63 
    64 int main()
    65 {
    66   n = read();
    67   scanf("%s", s);
    68   init(); manacher();
    69   for(int i = 1; i <= n; ++i)
    70     {
    71       enn[i - p[i] + 1]++;
    72       enn[i + 1]--;
    73       beg[i]++;
    74       beg[i + p[i]]--;
    75       ans = (ans + (p[i] >> 1) % mod) % mod;
    76     }
    77   ans = (ans * (ans - 1) >> 1) % mod;
    78   for(int i = 1, sum = 0; i <= n; ++i)
    79     {
    80       enn[i] += enn[i - 1]; beg[i] += beg[i - 1];
    81       if(i % 2 == 0) ans = (ans - (ll)sum * (ll)enn[i] % mod + mod) % mod, sum = (sum + beg[i]) % mod;
    82     }
    83   write(ans), enter;
    84   return 0;
    85 }
    View Code
  • 相关阅读:
    BZOJ 1391: [Ceoi2008]order
    BZOJ 4504: K个串
    2019 年百度之星·程序设计大赛
    POJ 2398 Toy Storage (二分 叉积)
    POJ 2318 TOYS (二分 叉积)
    HDU 6697 Closest Pair of Segments (计算几何 暴力)
    HDU 6695 Welcome Party (贪心)
    HDU 6693 Valentine's Day (概率)
    HDU 6590 Code (判断凸包相交)
    POJ 3805 Separate Points (判断凸包相交)
  • 原文地址:https://www.cnblogs.com/mrclr/p/9773530.html
Copyright © 2020-2023  润新知