【BZOJ2160】拉拉队排练(回文树)
2018-02-23 20:04
246 查看
题面
BZOJ题解
看着题目,直接构建回文树
求出每个回文串的出现次数
直接按照长度sort一下就行了
然后快速幂算一下答案就出来了
这题貌似可以用Manacher做吧
求出以每个字符为中心的回文串的最大长度
然后搞一下前缀和就行了
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<queue> using namespace std; #define ll long long #define RG register #define MAX 1200000 #define MOD 19930726 int size[MAX]; char ch[MAX]; int n,ans=1; ll K,sum; pair<in f47a t,int> S[MAX]; int fpow(int a,int b) { int s=1; while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;} return s; } struct PT { struct Node { int son[26]; int ff,len; }t[MAX]; int last,tot; void init() { t[tot=1].len=-1; t[1].ff=t[0].ff=1; } void extend(int c,int n,char *s) { int p=last; while(s[n-t[p].len-1]!=s )p=t[p].ff; if(!t[p].son[c]) { int v=++tot,k=t[p].ff; while(s[n-t[k].len-1]!=s )k=t[k].ff; t[v].len=t[p].len+2; t[v].ff=t[k].son[c]; t[p].son[c]=v; } size[last=t[p].son[c]]++; } void Calc() { for(int i=tot;i;--i)size[t[i].ff]+=size[i]; } }PT; int main() { scanf("%d %lld",&n,&K); scanf("%s",ch+1); PT.init(); for(int i=1;i<=n;++i)PT.extend(ch[i]-97,i,ch); PT.Calc(); for(int i=2;i<=PT.tot;++i)S[i-1]=make_pair(-PT.t[i].len,size[i]); sort(&S[1],&S[PT.tot]); for(int i=1;i<PT.tot;++i) { if(S[i].first%2==0)continue; ll pl=min(K,1ll*S[i].second); ans=1ll*ans*fpow(-S[i].first,pl)%MOD; K-=pl; if(!K)break; } if(!K)printf("%d\n",ans); else puts("-1"); return 0; }
相关文章推荐
- BZOJ 2160: 拉拉队排练 回文自动机
- 【BZOJ2160】拉拉队排练(回文树)
- [BZOJ2160]拉拉队排练(回文树)
- 回文树——BZOJ 2160: 拉拉队排练
- bzoj 2160: 拉拉队排练 回文自动机
- HYSBZ 2160 拉拉队排练(回文树)
- BZOJ 2160: 拉拉队排练
- bzoj 2160: 拉拉队排练 manachar+快速幂
- HYSBZ 2160 拉拉队排练(回文树)
- [BZOJ]2160 拉拉队排练 Manacher+快速幂
- BZOJ 2160 拉拉队排练
- [BZOJ2160]拉拉队排练
- BZOJ_2160_拉拉队排练_manacher
- BZOJ 2160: 拉拉队排练 manacher
- bzoj 2160: 拉拉队排练
- BZOJ 2160 拉拉队排练
- 回文树:【BZOJ2160】【国家集训队】拉拉队排练
- bzoj 2160: 拉拉队排练 (manacher+前缀和+快速幂)
- BZOJ 2160: 拉拉队排练
- bzoj 2160: 拉拉队排练