bzoj 2160(manacher+差分)
2017-08-02 22:46
148 查看
传送门
问题:对于给出的长度为n的字符串如果其回文串的数量比K少则输出-1, 否则输出所有回文串中长度为奇数的最长的前K个回文串的长度的乘积, 结果对于19930726取模输出。
由于只考虑奇数长度的回文子串,所以不用构造新串,直接在原串头尾添加”+”,”-“做标记后跑manacher,求出回文半径p[i]后用差分前缀和思想统计各长度回文串个数,最后乘的时候套个快速幂即可。
问题:对于给出的长度为n的字符串如果其回文串的数量比K少则输出-1, 否则输出所有回文串中长度为奇数的最长的前K个回文串的长度的乘积, 结果对于19930726取模输出。
由于只考虑奇数长度的回文子串,所以不用构造新串,直接在原串头尾添加”+”,”-“做标记后跑manacher,求出回文半径p[i]后用差分前缀和思想统计各长度回文串个数,最后乘的时候套个快速幂即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e6+4; const ll mod=19930726; char b[maxn]; int p[maxn]; int n; ll k,sum[maxn]; inline void manacher() { int id=0,mx=0; for (register int i=1;i<=n;++i) { p[i]=(mx>i)?min(mx-i,p[(id<<1)-i]):1; while (b[i+p[i]]==b[i-p[i]]) ++p[i]; if (mx<i+p[i]) mx=i+p[i],id=i; ++sum[0],--sum[p[i]+1]; } } ll fpow(ll a,ll b,ll mod) { ll ans=1; while (b) { if (b&1) ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } int main() { // freopen("bzoj 2160.in","r",stdin); memset(sum,0,sizeof(sum)); scanf("%d%lld",&n,&k); scanf("%s",b+1); b[0]='+',b[n+1]='-'; manacher(); for (register int i=1;i<=n;++i) sum[i]+=sum[i-1]; ll cnt=0,res=1; for (register int i=n;i>0;--i) { if (sum[i]+cnt<k) res=res*fpow((i<<1)-1,sum[i],mod)%mod,cnt+=sum[i]; else {res=res*fpow((i<<1)-1,k-cnt,mod)%mod,cnt=k;break;} } if (cnt^k) puts("-1"); else printf("%lld\n",res); return 0; }
相关文章推荐
- bzoj2160 拉拉队排练 manacher+差分
- [BZOJ 2160] 拉拉队排练 (manacher+差分数组+前缀和)
- BZOJ 2160: 拉拉队排练 manacher
- [BZOJ 2160] 拉拉队排练 Manacher+贪心
- BZOJ.2160.拉拉队排练(Manacher)
- BZOJ 2160 Manacher 解题报告
- BZOJ 2160 拉拉队排练
- BZOJ 2160 拉拉队排练
- BZOJ 2160 啦啦队 回文串 Manacher 快速幂
- [BZOJ]2160 拉拉队排练 Manacher+快速幂
- bzoj 2160: 拉拉队排练 (manacher+前缀和+快速幂)
- 【bzoj2160】拉拉队排练 manachar
- bzoj 2160: 拉拉队排练
- 【bzoj2160】拉拉队排练 manacher
- [bzoj2160]拉拉队排练 manacher+快速幂
- [BZOJ2160]拉拉队排练(manacher+快速幂)
- 【BZOJ 2160】拉拉队排练 回文树
- BZOJ 2160: 拉拉队排练 回文自动机
- BZOJ 2160: 拉拉队排练
- 回文树:【BZOJ2160】【国家集训队】拉拉队排练