题解 CF17E 【Palisection】
卡空间PAM,2010没有PAM,所以都是马拉车
众所周知,PAM拥有十分优秀的时间复杂度,但空间复杂度lj得不行
但这题卡空间,所以得用到邻接链表PAM
先讲思路
题目要求相交的回文子串对,这很难做
于是我们求补集,求不相交的回文子串对,再用总数减即可
求法和上文的最长双回文子串 类似
正反建一次PAM,存该位置结尾的回文子串个数,然后加法改乘法
自己领悟一下,挺简单的。
现在讲一下邻接链表PAM
注意:邻接链表PAM不是使空间变小了,而是用时间换空间
我们记边结构体\(line\)
存\(3\)个信息:\(nx,to,w\) 分别表示上一条边,这条边通向的节点编号,这条边是代表哪个字符
数组\(fir[i]\)表示\(i\)伸出的最后一条边的编号(头插式
当我们要寻找\(u\)的\(v\)儿子
我们就像邻接链表一样找,直到有一条边的\(w==v\)为止
找不到记得指根
int getson(int u,int v){
for(int i=u;i!=-1;i=l[i].nx)
if(l[i].w==v)return l[i].to;
return -1;
}
建点的时候把边建上
void insert(int u,int i){
int Fail=getfail(pre,i),ls=getfail(fail[Fail],i);
if(getson(fir[Fail],u)==-1){
if(getson(fir[ls],u)==-1)fail[++tot]=0; //找不到指根
else fail[++tot]=getson(fir[ls],u); //找到了
l[++cnt]=(line){fir[Fail],tot,u};fir[Fail]=cnt; //加边
len[tot]=len[Fail]+2;
ans[tot]=ans[fail[tot]]+1; //结尾回文子串个数
pre=tot;
}else
pre=getson(fir[Fail],u);
}
然鹅事实上你仍然过不了,你还要继续压空间,省掉一堆数组就可以过啦!
总代码:
#include<bits/stdc++.h>
#define maxn 2000005
#define mod 51123987
using namespace std;
char s[maxn];
int slen,b[maxn];
long long res;
int fail[maxn],len[maxn],ans[maxn],fir[maxn];
struct line{int nx,to,w;}l[maxn];
int tot,pre,cnt;
void init(){
memset(fir,-1,sizeof(fir));cnt=0;
fail[0]=1;len[1]=-1;tot=1;pre=0;
}
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 getson(int u,int v){
for(int i=u;i!=-1;i=l[i].nx)
if(l[i].w==v)return l[i].to;
return -1;
}
void insert(int u,int i){
int Fail=getfail(pre,i),ls=getfail(fail[Fail],i);
if(getson(fir[Fail],u)==-1){
if(getson(fir[ls],u)==-1)fail[++tot]=0;
else fail[++tot]=getson(fir[ls],u);
l[++cnt]=(line){fir[Fail],tot,u};fir[Fail]=cnt;
len[tot]=len[Fail]+2;
ans[tot]=ans[fail[tot]]+1;
pre=tot;
}else
pre=getson(fir[Fail],u);
}
int main(){
int n;
scanf("%d",&n);
scanf("%s",s);slen=strlen(s);init();
reverse(s,s+slen);
for(int i=0;i<slen;i++)insert(s[i]-'a',i),b[slen-i-1]=ans[pre];
for(int i=slen-1;i>=0;i--)b[i]+=b[i+1],b[i]%=mod;
reverse(s,s+slen);init();
for(int i=0;i<slen-1;i++){
insert(s[i]-'a',i);int x=ans[pre];
res+=(1ll*x*b[i+1])%mod,res%=mod;
}
printf("%lld\n",((1ll*b[0]*(b[0]-1)/2ll)%mod-res+mod)%mod);
return 0;
}
题解 CF17E 【Palisection】的更多相关文章
- CF17E Palisection(manacher/回文树)
CF17E Palisection(manacher/回文树) Luogu 题解时间 直接正难则反改成求不相交的对数. manacher求出半径之后就可以差分搞出以某个位置为开头/结尾的回文串个数. ...
- CF17E Palisection——优秀的综合计数题
题意翻译 给定一个长度为n的小写字母串.问你有多少对相交的回文子 串(包含也算相交) . 输入格式 第一行是字符串长度n(1<=n<=2*10^6),第二行字符串 输出格式 相交的回文子串 ...
- CF17E Palisection manacher
题面:洛谷(带翻译) 题解: 直接求相交不太好求,所以考虑求不相交的回文串对数. 设ll[i]表示以i为开头的回文串个数,rr[i]表示结尾<=i的回文串个数. 然后不相交的回文串对数显然就是对 ...
- CF17E Palisection(回文自动机)
题意翻译 给定一个长度为n的小写字母串.问你有多少对相交的回文子 串(包含也算相交) . 输入格式 第一行是字符串长度n(1<=n<=2*10^6),第二行字符串 输出格式 相交的回文子串 ...
- CF17E Palisection(manacher)
题意 给出一个长度为N的字符串S,问S中有多少个回文子串对(i,j)使得i,j在S中的位置相交?(N<=2*106) 题解 #include<iostream> #include&l ...
- CF17E Palisection(回文树)
题意翻译 给定一个长度为n的小写字母串.问你有多少对相交的回文子 串(包含也算相交) . 输入格式 第一行是字符串长度n(1<=n<=2*10^6),第二行字符串 输出格式 相交的回文子串 ...
- CF17E Palisection 差分+manacher算法
题目大意: 给定一个串$S$,询问有多少对相交的回文子串 直接做的办法: 我们先考虑求出以$i$为结尾的串的数量,这个很好统计 之后,我们再求出所有包含了点$i$的回文串的数目 这个相当于在$i$的左 ...
- CF17E Palisection
题意 给定一个长度为n的小写字母串.问你有多少对相交的回文子串(包含也算相交) 相交的回文子串个数 \(mod\ 51123987\) Sol 求相交的回文子串不太好求 考虑用总数减去不相交的回文串个 ...
- CF17E Palisection (回文自动机+DP)
题目传送门 题目大意:给你一个字符串,让你求出有多少对相交的回文子串 啊啊啊啊降智了,我怎么又忘了正难则反! 求相交会很难搞.把问题转化成求互不相交的回文子串再减一下就行了 先利用$PAM$求出以每个 ...
随机推荐
- Linux防火墙firewalld安全设置
背景描述 防火墙是具有很好的保护作用.入侵者必须首先穿越防火墙的安全防线,才能接触目标计算机.在公司里数据安全是最重要的,要求安全部门进行全公司进行服务器防火墙安全搭建,在原有的基础上进行安全的防火墙 ...
- 认识Html DOM
1.认识HTML DOM HTML Document Object Model 即:超文本标记语言-文档对象模型 HTML DOM理解为网页的API.它将网页中的各个元素都看作一个个对象,从而使网页中 ...
- python unittest控制用例的执行顺序
为什么要进行顺序控制呢?使用过testng的同学就知道,它相对于junit来说有更强大的功能,其中的一个功能就是依赖测试.什么是依赖测试呢?简单的说一下就是,A方法运行时,其中有个变量的取值是B方法的 ...
- 清理缓存的方法 #DF
移动应用在处理网络资源时,一般都会做离线缓存处理,其中以图片缓存最为典型,其中很流行的离线缓存框架为SDWebImage. 但是,离线缓存会占用手机存储空间,所以缓存清理功能基本成为资讯.购物.阅读类 ...
- llinux_2
1.显示/etc目录下,以非字母开头,后面跟了一个字母以及其它任意长度任意字符的文件或目录 [root@lhq ~]#ls /etc/ | grep "^[^[:alpha:]][[:alp ...
- 【论文总结】Zero-Shot Semantic Segmentation
论文地址:https://arxiv.org/abs/1906.00817 代码:https://github.com/valeoai/ZS3 一.内容 Step 0:首先使用数据集(完全不包含 Un ...
- 适用于小白:VSCode搭建Vue项目,最详细的搭建步骤哦
在vscode上搭建一个vue项目---初学总结. 1.假设Vscode.nodejs等已经安装好了. 2.全局安装vue-cli,vue-cli可以帮助我们快速构建Vue项目. 安装命令: npm ...
- 常用文本处理命令 & 三剑客之 sed
今日内容 文本处理命令 Linux 三剑客之 sed 内容详细 文本处理命令 1.sort : 文件内容排序 默认按照文件隔行内容的第一个字符大小进行排序(默认是升序) 默认输出文本结果 sort [ ...
- Solution -「AGC 013E」「AT 2371」Placing Squares
\(\mathcal{Description}\) Link. 给定一个长度为 \(n\) 的木板,木板上有 \(m\) 个标记点,第 \(i\) 个标记点距离木板左端点的距离为 \(x_i\ ...
- Azure AD(六)添加自定义域名
一,引言 每当我们在 Azure Portal 上创建新的租户时,都会在设置租户的 "初始域名" 后加上 ".onmicrosoft.com",默认情况下 &q ...