• 【题解】Palindrome pairs [Codeforces159D]


    【题解】Palindrome pairs [Codeforces159D]

    传送门:(Palindrome) (pairs) ([CF159D])

    【题目描述】

    给定一个长度为 (N) 的字符串 (S),求有多少四元组 ((l_1,r_1,l_2,r_2)) 满足 (1 leqslant l_1 leqslant r_1 leqslant l_2 leqslant r_2 leqslant N)(S[l1...r1],) ([Sl2...r2]) 都是回文串。

    【样例】

    样例输入:
    aa
    样例输出:
    1
    
    样例输入:
    aaa
    样例输出:
    5
    
    样例输入:
    abacaba
    样例输出:
    36
    

    【数据范围】

    (100\%) (n leqslant 2000)


    【分析】

    由于这道题数据较小,直接写暴力也可以过(见隔壁大佬),但(Palisection) ([CF17E])就过不了了,这时候我们需要更高效的算法。

    首先,用 (Manacher) 求出一个 (f[i]) 数组,用其表示以 (a[i]) 为中心最多可以匹配的回文串半径,那么就可以递推了。

    实际上是要求互不相交的回文串对数,与(Palisection) ([CF17E])恰恰相反。
    对于每一个回文串 ([l,r]),凡是 ([1,l-1]) 中的回文串都可以与之形成合法四元组,可以用 (st[i],ed[i]) 分别表示以 (a[i]) 开头和以 (a[i]) 结尾的回文串个数,那么 (ans=sum_{i=2}^{n}{sum_{j=1}^{i-1}st[j]*ed[i]})

    初始化时要对 (st,ed) 进行区间修改,查询时是单点查询,可以用线段树或者树状数组,不过有点麻烦,可以直接存差分数组,然后统计答案时用一个变量 (S) 优化掉枚举 (st) 求和的过程。

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

    【Code】

    #include<cstring>
    #include<cstdio>
    #define LL long long
    #define Re register int
    const int N=2003;
    int n=1,m,p,q,f[N<<1];LL S,ans,st[N<<1],ed[N<<1];char a[N],b[N<<1];//记得开long long
    inline int min(Re a,Re b){return a<b?a:b;}
    int main(){
        scanf("%s",a+1),m=strlen(a+1);
        for(Re i=1;i<=m;++i,++n)b[++n]=a[i];//玄学填空法
        b[0]=1,b[n+1]=2;//放置首尾两边多余部分被匹配
        for(Re i=1;i<=n;++i){//Manacher
        	f[i]=q>i?min(f[(p<<1)-i],q-i):1;
        	while(b[i-f[i]]==b[i+f[i]])++f[i];
        	if(i+f[i]>q)q=(p=i)+f[i];
        }
        for(Re i=1;i<=n;++i){
        	++st[i-f[i]+1],--st[i+1];//区间修改[i-f[i]+1,i]
        	++ed[i],--ed[i+f[i]-1+1];//区间修改[i,i+f[i]-1]
        }
        for(Re i=1;i<=n;++i){
        	st[i]+=st[i-1],ed[i]+=ed[i-1];//差分求和算出单个的st,ed
        	if(!(i%2))ans+=S*st[i],S+=ed[i];
        }
        printf("%lld",ans);
    }
    
  • 相关阅读:
    NserviceBus+rabbitmq
    c#调用Mysql带参数的存储过程
    datatable list 之前相互转换
    (gridcontrol等)通用导出excel z
    异步数据库查询 Z
    Gridview导出EXCEL(多页) z
    [自制简单操作系统] 4、计时器(线性表实现优化中断)
    [JAVA] 基于TCP的起重机运行模拟器
    [自制简单操作系统] 3、内存管理和窗口叠加
    [自制简单操作系统] 2、鼠标及键盘中断处理事件[PICGDTIDTFIFO]
  • 原文地址:https://www.cnblogs.com/Xing-Ling/p/11392261.html
Copyright © 2020-2023  润新知