题解 P1659 【[国家集训队]拉拉队排练】
一眼可得PAM
如果没学过PAM的可以看这里:PAM学习小结
我们令PAM上多记录一个信息\(sum\),表示该节点表示串在原串上出现了多少次。
当我们处理完了\(sum\),对于长度\(len\)为奇数的节点的信息\(sum\)计入数组\(a[i]\).
\(a[i]\)为长度为\(i\)的回文子串出现次数。
\(a[i]\)降序排序后累加答案快速幂处理一下即可,不需太多点拨
重点来了
讲一下怎么处理\(sum\)
我们可以发现当一个节点\(u\)的\(sum+1\),那么\(fail[u]\)的\(sum\)也要\(+1\)
熟悉AC自动机的OIer可以敏锐的察觉到可以用拓扑排序了(例如我
建PAM的时候打个标记,最后统一一个拓扑排序向\(fail\)去更新\(sum\)即可
queue<int >q; //in数组为fail入边数量
void tuopu(){
for(int i=0;i<=tot;i++)if(in[i]==0)q.push(i);
while(!q.empty()){
int u=q.front();q.pop();
sum[fail[u]]+=sum[u];in[fail[u]]--;
if(in[fail[u]]==0)q.push(fail[u]);
}
}
好像没什么问题,多一个拓扑排序就行了
但真的如此吗?
我们观察PAM和AC自动机的区别
AC自动机是建好\(Trie\)后再进行\(getFail\)的,\(fail\)的节点编号是会大于自身节点编号
而PAM不会出现这种情况,PAM\(fail\)定义不同于AC自动机,构建使用增量法,保证了\(fail\)的节点编号一定小于自身节点编号。
所以就可以不用拓扑排序了,直接一个\(for\)从后到前更新即可
for(int i=tot;i>=0;i--)sum[fail[i]]+=sum[i];
总代码:
#include<bits/stdc++.h>
#define maxn 1010001
#define ll long long
#define mod 19930726
using namespace std;
char s[maxn];
int fail[maxn],len[maxn],trie[maxn][26],trans[maxn];
long long sum[maxn];
int per,slen,tot;
long long a[maxn],K,ans=1;
int getfail(int x,int i){
while(i-len[x]-1<0||s[i-len[x]-1]!=s[i])x=fail[x];
return x;
}
int gettrans(int x,int i){
while(((len[x]+2)<<1)>len[tot]||s[i-len[x]-1]!=s[i])x=fail[x];
return x;
}
void insert(int u,int i){
int Fail=getfail(per,i);
if(!trie[Fail][u]){
len[++tot]=len[Fail]+2;
fail[tot]=trie[getfail(fail[Fail],i)][u];
trie[Fail][u]=tot;
if(len[tot]<=2)trans[tot]=fail[tot];
else{
int Trans=gettrans(trans[Fail],i);
trans[tot]=trie[Trans][u];
}
}
per=trie[Fail][u];
sum[per]++; //记录sum
}
ll qpow(ll n,ll m){
ll ans=1ll;
while(m){
if(m&1){ans=ans*n;ans%=mod;}
n=n*n;n%=mod;m>>=1;
}return ans%mod;
}
int main(){
scanf("%d%lld",&slen,&K);
scanf("%s",s);
fail[0]=1;len[1]=-1;tot=1;
for(int i=0;i<slen;i++)insert(s[i]-'a',i);
for(int i=tot;i>=1;i--)sum[fail[i]]+=sum[i]; //更新sum
for(int i=2;i<=tot;i++)a[len[i]]+=sum[i],a[len[i]]%=mod; //长度处理
for(int i=slen;i>=1;i--){ //答案处理
if(i%2==1){
if(K>=a[i]){
ans*=qpow(i,a[i]);ans%=mod;
K-=a[i];
}else{
ans*=qpow(i,K);ans%=mod;
K-=K;
break;
}
}
}
if(K==0) //判-1
printf("%lld\n",ans%mod);
else
printf("-1\n");
return 0;
}
题解 P1659 【[国家集训队]拉拉队排练】的更多相关文章
- luogu P1659 [国家集训队]拉拉队排练
唔....话说好久没有发布题解了(手痒痒了 首先特别鸣谢lykkk大佬今天下午教我Manacher算法,甚是感谢 为了体现学习成果,写一篇蒟蒻版的题解(大佬勿喷 言归正传 题面——>在这儿 首先 ...
- 洛谷 P1659 [国家集训队]拉拉队排练(Manacher)
题目链接:https://www.luogu.com.cn/problem/P1659 思路: 首先跑一遍Manacher,用$cnt_i$记录长为$i$的回文串有多少个. 所记录的$cnt$并不是最 ...
- P1659 [国家集训队]拉拉队排练
思路 求出cnt和len之后,直接乘起来即可 代码 #include <cstdio> #include <algorithm> #include <cstring> ...
- Manacher【p1659】 [国家集训队]拉拉队排练
题目描述 n个女生举牌子(只含有26个小写字母,长度为n的字符串), 如果连续的一段女生,有奇数个,并且她们手中的牌子所写的字母,从左到右和从右到左读起来一样,那么这一段女生就被称作和谐小群体. 现在 ...
- 【洛谷 P1659】 [国家集训队]拉拉队排练(manacher)
题目链接 马拉车+简单膜你 #include <cstdio> #include <cstring> #include <algorithm> using name ...
- [回文树][BZOJ2160][国家集训队]拉拉队排练
题面 Description 艾利斯顿商学院篮球队要参加一年一度的市篮球比赛了.拉拉队是篮球比赛的一个看点,好的拉拉队往往能帮助球队增加士气,赢得最终的比赛.所以作为拉拉队队长的楚雨荨同学知道,帮助篮 ...
- [国家集训队]拉拉队排练 Manancher_前缀和_快速幂
Code: #include <cstdio> #include <algorithm> #include <cstring> using namespace st ...
- [国家集训队] 拉拉队排练 - Manacher
用 Manacher 跑出回文串长,注意这里不需要偶数长度所以不需要对串做一些奇怪的处理 然后用前缀和搞一下,计算答案时跑快速幂即可 #include <bits/stdc++.h> us ...
- 【题解】国家集训队礼物(Lucas定理)
[国家集训队]礼物(扩展Lucas定理) 传送门可以直接戳标题 172.40.23.20 24 .1 答案就是一个式子: \[ {n\choose \Sigma_{i=1}^m w}\times\pr ...
随机推荐
- Base64补充
1.Base64简单说明 描述:Base64可以成为密码学的基石,非常重要. 特点:可以将任意的二进制数据进行Base64编码 结果:所有的数据都能被编码为并只用65个字符就能表示的文本文件. 65字 ...
- ubuntu 修改文件及文件夹的权限
转载请注明来源:https://www.cnblogs.com/hookjc/ 打开终端进入你需要修改的目录然后执行下面这条命令chmod 777 * -R全部子目录及文件权限改为 777 来源:py ...
- webpack热更新 同时导出文件到本地
webpack 配置热更新后,文件配置导出到本地 安装 npm i webpack-dev-server-output --save-dev 引入 const WebpackDevServerOutp ...
- iOS应用启动main函数
#import <UIKit/UIKit.h> #import "AppDelegate.h" int main(int argc, char * argv[]) { ...
- 实现“手机qq”侧滑菜单 -- 吴欧
基本数据采集 经过体验,手机QQ采用的应该是线性动画,即视图缩放比例等随手指在屏幕上滑动的距离以一次方程的形式变化. 提取基本数据,向右侧滑达到最大幅度时: 1. 右侧主视图左边界距离屏幕左边界的 ...
- 简介GitHub的使用方法--管理个人代码
转自 http://blog.csdn.net/tengyeyijiu/article/details/46446283git是一个分布式版本控制系统,最初由linus torvalds编写,用作Li ...
- jenkins插件Publish Over SSH因安全问题下架
最近用docker新搭建了一个jenkins,安装插件的时候发现publish over ssh找不到了,官方给出的解释是存在安全隐患于2022.01.12暂停分发,官方解释如下:https://ww ...
- WEB前端开发--2(HTML基础)
HTML基础 HTML不分大小写 1.HTML概述 HTML(HyperText MarkUp Language)"超文本标记语言",他是制作网页的标准语言 1.1 标签--元素 ...
- Solution -「AGC 029E」「AT 4504」Wandering TKHS
\(\mathcal{Description}\) Link. 给一棵 \(n\) 个点的树,从某个点出发,遍历时必须走到已经走过的连通块所邻接的编号最小的结点.求从每个点出发,走到 \(1\ ...
- Python:pathlib模块
Blog:博客园 个人 关于panthlib模块 pathlib模块提供表示文件系统路径的类,其语义适用于不同的操作系统.路径类被分为提供纯计算操作而没有 I/O 的纯路径,以及从纯路径继承而来但提供 ...