bzoj4650: [Noi2016]优秀的拆分 hash
2024-09-08 11:15:50
好气啊,没开longlong又biubiu了
底层:
用hash或者奇奇怪怪的算法兹磁logn求最长公共前后缀
思路:
统计出从一个点开始和结束的形如AA的子串的个数
统计的时候把相邻的结果相乘加起来就好了
#include <bits/stdc++.h>
#define MOD 998244353
#define ad(x,y,z) t[x][y]++,t[x][z+1]--
using namespace std;
long long T,n,LOG;
char ch;
long long a[],t[][],mi[];
long long Mi[],ha[][];
int main()
{
for(scanf("%d",&T);T;T--)
{
for(ch=getchar();!isalpha(ch);ch=getchar());
for(n=;isalpha(ch);ch=getchar())
a[++n]=ch-'a';
LOG=;
for(int i=;i<=n;i<<=,++LOG) mi[LOG]=i;
Mi[]=;
for(int i=;i<=n;i++)
Mi[i]=Mi[i-]*%MOD;
for(int i=;i<=n;i++)
ha[i][]=a[i];
for(int i=;i<=LOG;i++)
for(int j=;j<=n-mi[i]+;j++)
ha[j][i]=ha[j][i-]*Mi[mi[i-]]%MOD+ha[j+mi[i-]][i-];
for(int i=;i<=n;i++)
t[][i]=,
t[][i]=;
for(int len=;len<=n/;len++)
{
for(int Now=,Nex=+len;Nex<=n;Now=Nex,Nex=Now+len)
{
int now=Now,nex=Nex;
for(int i=LOG;i>=;i--)
if(nex+mi[i]-<=n)
if(ha[now][i]==ha[nex][i])
now+=mi[i],nex+=mi[i];
int lcp=min(now-Now,len);
now=Now,nex=Nex;
for(int i=LOG;i>=;i--)
if(now>=mi[i])
if(ha[now-mi[i]+][i]==ha[nex-mi[i]+][i])
now-=mi[i],nex-=mi[i];
int lcs=min(Now-now,len);
now=Now,nex=Nex;
if(lcp+lcs>=len)
{
ad(,nex-lcs+len,nex+lcp-);
ad(,now-lcs+,now+lcp-len);
}
}
}
for(int i=;i<=n;i++)
t[][i]+=t[][i-],
t[][i]+=t[][i-];
long long ans=;
for(int i=;i<n;i++)
ans+=t[][i]*t[][i+];
printf("%lld\n",ans);
}
return ;
}
最新文章
- sh4.case语句
- 自己动手写ORM框架
- JavaScript继承
- HDU 4067 hdoj 4067 Random Maze 最小费用流
- col-md-*,col-xs-*
- 【译】怎样编写移动优先的CSS
- HDFS的Trash回收站功能
- Tuning Spark
- ArcMap中";开始编辑";遇到一个或多个带有警告的图层“如果继续,可能无法编辑某些图层”的警告框
- SQL调用系统存储过程整理
- CentOS5下配置JDK1.6+TOMCAT6
- linux常用svn命令(转载)
- win7系统64位安装oracle10g
- iphone手机上的click和touch
- 从0移植uboot (二) _启动流程分析
- [LeetCode] Valid Tic-Tac-Toe State 验证井字棋状态
- php mysqli 的使用方法
- Unity 3D观察者设计模式-C#委托和事件的运用
- (线段树 区间查询更新) Can you answer these queries? -- hdu--4027
- [选译]MySQL5.7以上Zip版官方安装文档