zoukankan      html  css  js  c++  java
  • CF17E Palisection

    题意:给定一个长度为n的小写字母串。问你有多少对相交的回文子 串(包含也算相交) 。

    题目传送门

    日常敲模板2333

    首先,相交的很不好找。

    考虑等价问题,有多少对不相交的。用总数减去即可。

    对于一个点i,从i-hw[i]到i,所有点都可以作为以i为中点的回文串的起点,统计终点同理。于是,就可以差分了,最后O(n)扫一遍统计即可。

    代码简单。但这并不妨碍我写的丑。

    #include<bits/stdc++.h>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<deque>
    #include<list>
    #include<set>
    #include<vector>
    #include<iostream>
    #define ll long long
    #define re register
    #define inf 0x3f3f3f3f
    #define inl inline
    #define sqr(x) (x*x)
    //#define eps 1e-8
    #define debug printf("debug ");
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    //#pragma GCC optimize (2)
    //#pragma G++ optimize (2)
    using namespace std;
    const ll mod=51123987;
    const ll MAXN=2e6+10;
    inl ll read() {
    re ll x = 0; re int f = 1;
    char ch = getchar();
    while(ch<'0'||ch>'9') { if(ch== '-' ) f = -1; ch = getchar(); }
    while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x * f;
    }
    inl char readc() {
    char ch=getchar();
    while(('z'<ch||ch<'a')&&('Z'<ch||ch<'A')) ch=getchar();
    return ch;
    }
    inl void write(re ll x){
    if(x>=10)write(x/10);
    putchar(x%10+'0');
    }
    inl void writeln(re ll x){
    if(x<0) {x=-x;putchar('-');}
    write(x); puts("");
    }
    inl ll gcd(re ll x,re ll y){while(y^=x^=y^=x%=y);return x;}
    inl ll Lcm(re ll a,re ll b) {return a/gcd(a,b)*b;}
    inl void FR() {
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
    }
    inl void FC() {
    fclose(stdin);
    fclose(stdout);
    }
    ll n,nn,hw[MAXN<<1];
    char s[MAXN],ss[MAXN<<1];
    void manacher() {
    ll mr=0,mid=0;
    for(re ll i=1;i<=nn;i++) {
    if(i<mr) hw[i]=min(hw[(mid<<1)-i],mid+hw[mid]-i);
    else hw[i]=1;
    while(ss[i-hw[i]]==ss[i+hw[i]]) hw[i]++;
    if(i+hw[i]>mr) {mr=i+hw[i]-1;mid=i;}
    }
    }
    ll f[MAXN<<1],g[MAXN<<1];
    int main() {
    // FR();
    n=read();scanf("%s",s+1);
    ss[0]=ss[1]='#';nn=n<<1|1;ll sum=0;
    for(re ll i=1;i<=n;i++) {ss[i<<1]=s[i];ss[i<<1|1]='#';}
    manacher();re ll tot=0;
    for(re ll i=1;i<=nn;i++) {
    tot=(tot+(hw[i]-1)/2)%mod;
    if(!(i%2)) tot=(tot+1)%mod;
    }
    if(tot%2) {sum=((tot-1)/2*tot)%mod;}
    else {sum=(tot/2*(tot-1))%mod;}
    for(re ll i=1;i<=nn;i++) {
    if(i%2) {
    f[i-hw[i]+2]++;f[i+1]--;
    g[i+hw[i]]--;g[i+1]++;
    }
    else {
    f[i-hw[i]+2]++;f[i+2]--;
    g[i+hw[i]]--;g[i]++;
    }
    }
    for(re ll i=2;i<=nn;i+=2) {
    f[i]=(f[i]+f[i-2])%mod;
    g[i]=(g[i]+g[i-2])%mod;
    }
    f[nn+1]=0;
    for(re ll i=nn-1;i>=2;i-=2) {f[i]=(f[i]+f[i+2])%mod;}
    for(re ll i=2;i<=nn;i+=2) {sum=(sum-(g[i]*f[i+2])%mod+mod)%mod;}
    writeln((sum+mod)%mod);
    // FC();
    return 0;
    }

  • 相关阅读:
    [USACO][最短路]Cow Tours
    [USACO][枚举]Preface Numbering
    [USACO][枚举]Hamming Code
    [USACO][枚举]Healthy Holsteins
    [USACO][DAG上的动态规划]Sorting A Three-Valued Sequence
    [USACO][暴力]The Castle
    [USACO][枚举]Ski Course Design
    运算符重载must take either zero or one argument错误
    关于js鼠标事件综合各大浏览器能获取到坐标的属性总共以下五种
    鼠标滚轮事件封装
  • 原文地址:https://www.cnblogs.com/20020723YJX/p/9387656.html
Copyright © 2011-2022 走看看