zoukankan      html  css  js  c++  java
  • bzoj4480: [Jsoi2013]快乐的jyy

    【问题描述】

    给定两个字符串A和B,表示JYY的两个朋友的名字。我们用A(i,j)表示A
    字符串中从第i个字母到第j个字母所组成的子串。同样的,我们也可以定义B(x,y)。
    JYY发现两个朋友关系的紧密程度,等于同时满足如下条件的四元组(i,j,x,y)
    的个数:
    1:1<=i<=j<=|A|
    2:1<=x<=y<=|B|
    3:A(i,j)=B(x,y)
    4:A(i,j)是回文串
    这里表示字符串A的长度。
    JYY希望你帮助他计算出这两个朋友之间关系的紧密程度。
    建两个串的回文树,算出每个本质不同的回文串在两个串中出现次数,乘起来相加。
    #include<bits/stdc++.h>
    typedef long long i64;
    const int N=1e5+77;
    char s1[50007],s2[50007];
    int nx[N][26],fa[N],l[N],t[N][2],pv=2,ptr=2;
    int gf(int w,char*s,int i){
        while(s[i]!=s[i-1-l[w]])w=fa[w];
        return w;
    }
    void ins(char*s,int x){
        int c=s[x]-'A',p=gf(pv,s,x);
        if(!nx[p][c]){
            int np=nx[p][c]=++ptr;
            l[np]=l[p]+2;
            fa[np]=p==1?2:gf(fa[p],s,x)[nx][c];
        }
        pv=nx[p][c];
        ++t[pv][s==s2];
    }
    int main(){
        l[1]=-1;
        fa[1]=fa[2]=1;
        scanf("%s%s",s1+1,s2+1);
        s1[0]=s2[0]=-1;
        for(int i=1;s1[i];++i)ins(s1,i);
        pv=2;
        for(int i=1;s2[i];++i)ins(s2,i);
        i64 ans=0;
        for(int w=ptr;w>2;--w){
            int f=fa[w];
            for(int d=0;d<2;++d)t[f][d]+=t[w][d];
            ans+=i64(t[w][0])*t[w][1];
        }
        printf("%llu
    ",ans);
        return 0;
    }
  • 相关阅读:
    RabbitMQ
    操作系统复习知识
    计算机网络相关知识复习
    转帖--Linux的文件检索(locate、find、which、whereis)
    go-ioutil
    使用wrk进行压测
    03x01 Java基础语法
    02x03 Hello World!!!
    02x02 环境搭建
    02x01 Java入门
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7423613.html
Copyright © 2011-2022 走看看