[国家集训队]拉拉队排练

这题的题意是 求出若干个 回文子串 按长度排序之后

算出 (prod_{i=1}^{k} len_i)

很显然我们可以用manacher算法 (O(n)) 求出每个回文子串的数量。但是只能求出最长的…那个

对于每个回文的字符串(len > 2) 任意删掉两个相同的字符 还是一个回文串

(cnt_i) 为 长度 为 i 的 回文子串的个数

那么 (cnt_i) = (sum_{j=i}^{n}) (cnt_j)[( (j) - (i) )%2==0]

然后考虑怎么乘起来。一个个乘显然很慢,我们计算出个数 就可以用 快速幂 直接计算这个了

答案就是 倒序枚举 然后快速幂就可以了。

code

#include<bits/stdc++.h>
using namespace std ;
#define int long long
#define fi first
#define se second
#define pb emplace_back
inline int read() {
	register int x = 0 , f = 1 ;
	register char c = getchar() ;
	for( ; ! isdigit(c) ; c = getchar()) if(c == '-') f = -1 ;
	for( ; isdigit(c) ; c = getchar()) x = (x << 1) + (x << 3) + (c & 15) ;
	return x * f ;
}
const int Mod = 19930726 ;
template < typename T > inline bool cmax(T & x , T y) {
	return x < y ? (x = y) , 1 : 0 ;
}
template < typename T > inline bool cmin(T & x , T y) {
	return x > y ? (x = y) , 1 : 0 ;
}
template < typename T > inline bool cabs(T & x) {
	return x > 0 ? 1 : (x = - x) , 0 ;
}
inline int QP(int x , int y , int Mod) {
	int ans = 1 ;
	for( ; y ; y >>= 1 , x = (x * x) % Mod)
		if(y & 1) ans = (ans * x) % Mod ;
	return ans ;
}
int n , m ;
const int N = 11000000 + 5 ;
char s[N] ;
char fix[N << 2] ;
int p[N] , ccnt[N] ;
inline void Manacher() {
  scanf("%s" , s + 1) ;
  int cnt = 0 ;
  fix[++ cnt] = '~' ;
  fix[++ cnt] = '%' ;
  for(register int i = 1 ; i <= n ; i ++)
  fix[++ cnt] = s[i] , fix[++ cnt] = '%' ;
  int l = 0 , r = 0 , mid = 0 ;
  for(register signed i = 1 ; i <= cnt ; i ++) {
    if(i <= r) p[i] = min(p[(mid << 1) - i] , r - i + 1) ;
    while(fix[i - p[i]] == fix[i + p[i]]) ++ p[i] ;
    if(p[i] + i > r) r = p[i] + i - 1 , mid = i ;
    ccnt[p[i] - 1] ++ ;
  }
  return ;
}
signed main() {
  n = read() ; m = read() ;
  Manacher() ;
  for(register int i = n ; i >= 1 ; i --)
    ccnt[i] += ccnt[i + 2] ;
  int ans = 1 ;
  for(register int i = n ; i >= 1 ; i --) {
    if(! ( i & 1 )) continue ;
    if(ccnt[i] <= m) { m -= ccnt[i] ; ans = (ans * QP(i , ccnt[i] , Mod)) % Mod ; }
    else { ans = (ans * QP(i , m , Mod)) % Mod , m = 0 ; break ; }
  } printf("%lld
" , ans ) ;
	return 0 ;
}
原文地址:https://www.cnblogs.com/Isaunoya/p/11646020.html