题解 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 ...
随机推荐
- JSP中的请求转发与重定向
在说请求转发和重定向之前,得了解下JSP九大内置对象中的response和request response:将服务器端数据发送到客户端,可通过在客户端浏览器中显示,用户浏览页面的重定向以及在客户端创建 ...
- TCP连接的状态转换图深度剖析
转载请注明来源:https://www.cnblogs.com/hookjc/ 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接,如图1所示. (1)第一次握手:建立连接时 ...
- 使用CAShapeLayer做出圆形的进度条 —— #DF!
CircleView.h的内容如下: #import <UIKit/UIKit.h> @interface CircleView : UIView @property (nonatomic ...
- Linux-标准输入标准输出
标准输入(代码为0) 标准输出(代码为1) 标准错误输出(代码为2) 将标准输出重定向到一个文件 find /etc -name fileA >list 等同于 find /etc -name ...
- .NET 6全文检索引擎Lucene.NET 4.8简单封装
前言 因为最近在做一个检索数据的工具.最开始用的Mysql8自带的全文检索功能.但是发现这货数据量超过百万之后,检索速度直线下降. 于是想到Lucene.net.花了一晚上时间做了简单的封装.可以直接 ...
- SpringDataJpa打印Sql详情(含参数)
Spring Data Jpa打印Sql详情(带sql参数) 这里使用的是 log4jdbc,yml配置文件里的数据源配置也要做相应的修改 pom文件引入 <dependency> < ...
- springcloud+gateway微服务整合swagger
单一的微服务集成swagger: maven: <dependency> <groupId>io.springfox</groupId> <artifactI ...
- 在Linux中设置php变量的方法
默认情况下已经安装好了PHP环境,并且知道安装好后的PHP文件路径,然后可以通过以下的方式设置PHP变量,快速执行PHP命令运行PHP文件. 环境:centos 第一步:vi ~/.bash_prof ...
- 4、架构--NFS实践、搭建web服务、文件共享
笔记 1.晨考 1.数据备份的方式有哪些 全量和增量 2.数据备份的命令有哪些,都有哪些优点缺点 cp : 本地,全量复制 scp :远程,全量复制 rsync :远程,增量复制 3.rsync的参数 ...
- 使用MyBatis拦截器后,摸鱼时间又长了。🐟
场景 在后端服务开发时,现在很流行的框架组合就是SSM(SpringBoot + Spring + MyBatis),在我们进行一些业务系统开发时,会有很多的业务数据表,而表中的信息从新插入开始,整个 ...