链接: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