题目地址:https://www.lydsy.com/JudgeOnline/problem.php?id=4480

题目:


Description

【故事背景】

JYY在JSOI有很多很多的好朋友,比如PUPPY,KFC还有PUPPUP。因为

有了这么多的好朋友,所以JYY每天都很快乐。某天,JYY发现好朋友之间关

系的好坏和名字有很大的关系,比如PUPPY和PUPPUP的关系就特别好,但是

和KFC的关系就很一般。JYY苦思冥想终于发现了其中的规律,现在JYY想知

道两个朋友之间关系的好坏,你能帮助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希望你帮助他计算出这两个朋友之间关系的紧密程度。

Input

数据包行两行由大写字母组成的字符串A和B
1≤|A|,|B|≤50000。

Output

包含一行一个整数,表示紧密程度,也就是满足要求的4元组个数

Sample Input

PUPPY
PUPPUP

Sample Output

17

解题思路:


对第一个字符串构造回文树,将last和n重置为0,在当前回文树的基础上不添加重复节点的继续构造回文树,相当于两棵回文树的合并,并统计两个字符串中每个节点的cnt[]值,最终结果:     ,其中p是最后一个节点的编号(程序中应该是p-1)

以样例为例,建立的回文树如下:

黑线表示在当前回文串两侧加新的字符形成新的回文串,如0->a->b表示在?️的两侧加a形成aa,在aa的两侧加b形成baab

红线表示第一个字符串的fail指针

蓝线表示第二个字符串新产生的fail指针

ac代码:


#include <bits/stdc++.h>
using namespace std;
const int maxn = 50005;
typedef long long ll;
int fail[maxn], cnt1[maxn], cnt2[maxn], len[maxn], nxt[maxn][26], s1[maxn], s2[maxn];
int last, n, p, ln;
char ss[maxn];
int newnode(int l,int cnt[]) //l是节点对应的最长回文子串的长度
{for(int i = 0; i < 26; i++)nxt[p][i] = 0;len[p] = l;cnt[p] = 0;return p++;
}
void init()
{p = 0, last = 0, n = 0, s1[0] = -1, s2[0] = -1;newnode(0,cnt1); // p=0的初始化newnode(-1,cnt1); // p = 1的初始化,之后 p = 2fail[0] = 1;fail[1] = 0;
}
int get_fail(int x,int s[])
{while(s[n - len[x] - 1] != s[n])x = fail[x];return x;
}
void insert(int c, int s[],int cnt[]) // c = ch - 'a'
{s[++n] = c;int cur = get_fail(last,s);if(!nxt[cur][c]){int now = newnode(len[cur] + 2,cnt); //now表示当前节点编号fail[now] = nxt[get_fail(fail[cur], s)][c];nxt[cur][c] = now;}last = nxt[cur][c];//当前节点编号cnt[last]++;//以last为结尾的最长回文子串对应的数目+1
}
void count()
{for(int i = p - 1; i >= 2; i--) //从后往前更新{cnt1[fail[i]] += cnt1[i];cnt2[fail[i]] += cnt2[i];}
}
int main()
{//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);init();scanf("%s", ss+1);ln = strlen(ss+1);for(int i = 1; i <= ln; i++)insert(ss[i] - 'A', s1, cnt1);scanf("%s", ss+1);last = 0, n = 0;ln = strlen(ss+1);for(int i = 1; i <= ln; i++)insert(ss[i] - 'A', s2, cnt2);count();ll ans = 0;for(int i = 2; i < p; i++)ans += (1LL * cnt1[i] * cnt2[i]);printf("%lld\n", ans);return 0;
}

【BZOJ4480】快乐的jyy(统计两个字符串中相同的回文串-回文树合并)相关推荐

  1. 找出两个字符串中最大子字符串,如abractyeyt,dgdsaeactyey的最大子串为actyet

    // 最大子字符串.cpp : 定义控制台应用程序的入口点. // //找出两个字符串中最大子字符串,如"abractyeyt","dgdsaeactyey"的 ...

  2. 找出两个字符串中最长的相同子字符串

    //找出两个字符串中最长的相同子字符串public class Stringdemo {public static void main(String[] args) {String str1 = ne ...

  3. 查找两个字符串中相同字符串_使两个字符串相同的最低成本

    查找两个字符串中相同字符串 Problem statement: 问题陈述: Given two strings string1 and string2 find the minimum cost r ...

  4. String类型的算法题(获取子串在主串中出现的次数)和(获取两个字符串中最大相同子串)-Java代码实现

    Java获取子串在主串中出现的次数 package BaiYSExer2;import org.junit.Test; /*** @author Baiysmart* @create 2020-03- ...

  5. java基础—找出两个字符串中最大的子串

    // 找一个字符串的最大子串public static void main(String[] args) {String s1 = "qwerabcdtyuiop";String ...

  6. 找出两个字符串中所有共同的字符_面试中的两个字符串问题竟给我整懵了?!| 原力计划...

    作者 | 一路向维 责编 | 王晓曼 出品 | CSDN博客 昨天收到通知,今天有个面试,一家魔都中型电商公司,名字咱就不说了.内心顿时踌躇满志.跃跃欲试,晚上还翻看面试题,做准备. 到了目的地之后, ...

  7. 获取两个字符串中最大相同子串

    题目说明: 获取两个字符串中最大相同子串.比如:str1 = "abcwerthelloyuiodefabcdef";str2 = "cvhellobnm"提示 ...

  8. 4.请编写一个函数void fun(char *tt,int pp[]),统计在tt字符串中“a”到“z”26个字母各自出现的次数,并依次放在pp所指数组中。

    4.请编写一个函数void fun(char *tt,int pp[]),统计在tt字符串中"a"到"z"26个字母各自出现的次数,并依次放在pp所指数组中. ...

  9. 写一函数,将两个字符串中的元音字母复制到另一个字符串,然后输出。

    写一函数,将两个字符串中的元音字母复制到另一个字符串,然后输出. #include<stdio.h> #include<string.h> char f(char a[],ch ...

  10. 1.统计所输入字符串中单词的个数。2.删除一个list里面重复元素。3.将列表中的偶数变成它的平方,奇数保持不变。4.输入字符串,将其每个字符的ASCII码形成列表并输出.5.猜单词游戏

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 题目: 1.统计所输入字符串中单词的个数,单词之间用空格分隔. 代码: print("请输入字符(以空格隔开):" ...

最新文章

  1. alert 返回页面 刷新_详解 HTML 页面原生的生命周期事件
  2. 集群理论讲解(续三)
  3. [bzoj1061] [NOI2008]志愿者招募
  4. Lync 2010迁移Lync 2013 PART6:迁移CMS
  5. Word中插入参考文献及其引用并能够自动更新的方法
  6. android资源之res/raw和assets的异同
  7. 赛码输入输出java_赛码网-计算器的新功能(Java实现)
  8. 为什么PostgreSQL比MongoDB还快之完结篇(深挖单点索引查询)
  9. Android之日期时间选择器使用方法
  10. 算法设计与分析_算法设计与分析(第2版)第2章分治策略回顾
  11. 数据结构排序法之插入法
  12. linux下Qt cannot find -lGL错误的解决方法
  13. 云服务器 ECS(CentOS) 安装 Node
  14. JAVA组件使用---UUID使用方法
  15. Oracle数据库学习思维导图
  16. 涉密计算机用户密码操作规程,涉密计算机管理设置密码
  17. 掉头发厉害,是为什么呢?
  18. 【保险分享】出门旅游是否需要够买旅行险?
  19. 搜索python设计题的微信公众号_appium+python自动化42-微信公众号 (可能以后会遇到也遇到切换不了webview的问题 记录再此 还没试)...
  20. xxl-job集成钉钉群告警

热门文章

  1. JAVA求n个数里最小的k个_n个数 找到最小的k个数 几种解法 和java实现
  2. python 100 days github_GitHub - Andyhe2019/Python-100-Days: Python - 100天从新手到大师
  3. response对象设置返回状态_爬虫代理之设置
  4. mysql 循环 索引值,mysql:循环遍历表和alter table添加索引
  5. c段服务器维护,服务器 多c段
  6. 最新最全linux系统调优指南(centos7.X)
  7. react privateRoute
  8. HTTP 连接管理进化论
  9. CountDownLatch 多线程使用示例
  10. 转载——yum源的超级简单配置