牛客国庆集训派对Day3 - F.Palindrome 回文树 后缀自动机

链接:https://www.nowcoder.com/acm/contest/203/F
来源:牛客网
 

题目描述

修修在蒜头送给他的奖杯上看到了一个长度为n的字符串s。
他希望从s中选择两个非空子串a,b(可以有重叠的部分),使得它们拼起来是一个回文串。
修修很快就算出了方案数,他听说你也会数数,就让你也来解决一下这个问题。两个方案不同当且仅当a,b中至少一个的长度或位置不同。

输入描述:

第一行一个整数n (1 ≤ n ≤ 2*105),第二行一个字符串s。保证s只包含小写字母。

输出描述:

输出一行一个整数表示方案数。

题解:

设原串是s,翻转后是t。

那么问题就是找原串和翻转后的串相同的子串数,还有一种就是两边是相同的串,中间可以加任意回文串。

所以我们找到以每个位置结尾的回文串个数,然后把原串s插入后缀自动机,在这个后缀自动机上跑翻转的串t,找到所有和t当前子串相同的串个数,乘上t前一个下标的回文串个数即可。

结果需要用int128。

代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <bitset>
#include <map>
#include <vector>
#include <stack>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#include <ctime>
#include <assert.h>
#ifdef LOCAL
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
#else
#define debug(x) 1;
#endif

#define chmax(x,y) x=max(x,y)
#define chmin(x,y) x=min(x,y)
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define lowbit(x) x&-x
#define mp make_pair
#d
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值