bzoj4650: [Noi2016]优秀的拆分 hash
好气啊,没开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 ;
}
bzoj4650: [Noi2016]优秀的拆分 hash的更多相关文章
- BZOJ4650: [Noi2016]优秀的拆分(hash 调和级数)
题意 题目链接 Sol NOI的题都这么良心么.. 先交个\(n^4\)暴力 => 75 hash优化一下 => 90 然后\(90\)到\(100\)分之间至少差了\(10\)难度台阶= ...
- [UOJ#219][BZOJ4650][Noi2016]优秀的拆分
[UOJ#219][BZOJ4650][Noi2016]优秀的拆分 试题描述 如果一个字符串可以被拆分为 AABBAABB 的形式,其中 A 和 B 是任意非空字符串,则我们称该字符串的这种拆分是优秀 ...
- BZOJ4650 [NOI2016]优秀的拆分 【后缀数组】
题目 如果一个字符串可以被拆分为 AABBAABB 的形式,其中 AA 和 BB 是任意非空字符串,则我们称该字符串的这种拆 分是优秀的.例如,对于字符串 aabaabaa,如果令 A=aabA=aa ...
- UOJ#219/BZOJ4650 [NOI2016]优秀的拆分 字符串 SA ST表
原文链接http://www.cnblogs.com/zhouzhendong/p/9025092.html 题目传送门 - UOJ#219 (推荐,题面清晰) 题目传送门 - BZOJ4650 题意 ...
- BZOJ4650: [Noi2016]优秀的拆分
考场上没秒的话多拿5分并不划算的样子. 思想其实很简单嘛. 要统计答案,求以每个位置开始和结束的AA串数量就好了.那么枚举AA中A的长度L,每L个字符设一个关键点,这样AA一定经过相邻的两个关键点.计 ...
- BZOJ4650 NOI2016优秀的拆分(后缀数组)
显然只要求出以每个位置开始的AA串数量就可以了,将其和反串同位置的结果乘一下,加起来就是答案.考虑对每种长度的字符串计数.若当前考虑的A串长度为x,我们每隔x个字符设一个关键点,求出相邻两关键点的后缀 ...
- [BZOJ4650][NOI2016]优秀的拆分(SAM构建SA)
关于解法这个讲的很清楚了,主要用了设关键点的巧妙思想. 主要想说的是一个刚学的方法:通过后缀自动机建立后缀树,再转成后缀数组. 后缀数组功能强大,但是最令人头疼的地方是模板太难背容易写错.用这个方法, ...
- bzoj千题计划317:bzoj4650: [Noi2016]优秀的拆分(后缀数组+差分)
https://www.lydsy.com/JudgeOnline/problem.php?id=4650 如果能够预处理出 suf[i] 以i结尾的形式为AA的子串个数 pre[i] 以i开头的形式 ...
- 题解【bzoj4650 [NOI2016]优秀的拆分】
Description 求对每一个连续字串将它切割成形如 AABB 的形式的方案数之和 Solution 显然 AABB 是由两个 AA 串拼起来的 考虑维护两个数组 a[i] 和 b[i] ,其中 ...
随机推荐
- 读取配置和动态配置(C方法)
读取配置 无论何种配置文件,定义了配置文件之后,都统一使用系统提供的C方法(可以借助Config单词来帮助记忆)来读取已有的配置.用法:C('参数名称') 例如,读取当前的URL模式配置参数:$mod ...
- C#高性能Socket服务器SocketAsyncEventArgs的实现(IOCP)
网址:http://blog.csdn.net/zhujunxxxxx/article/details/43573879 引言 我一直在探寻一个高性能的Socket客户端代码.以前,我使用Socket ...
- MySQL活动期间制定月份注册用户下单情况_20161029
在10.29到10.31号期间 10月新注册的用户订单金额满600元赠与优惠券 #3天内订单满600元且10月注册的用户订单明细 SELECT a.城市,a.用户ID,b.用户名称,DATE(b.注册 ...
- Oracle数据库导入、导出(远程、10g、11g)
1 查看oracle的版本信息 (1)用客户端连接到数据库,执行select * from v$instance 查看version项 (2)select * from pr ...
- Python3解leetcode Maximum Subarray
问题描述: Given an integer array nums, find the contiguous subarray (containing at least one number) whi ...
- Vijos1132:求二叉树的先序序列
描述 给出一棵二叉树的中序与后序排列.求出它的先序排列.(约定树结点用不同的大写字母表示,长度≤8). 格式 输入格式 第一行为二叉树的中序序列第二行为二叉树的后序序列 输出格式 一行,为二叉树的先序 ...
- java.lang.ClassCastException:android.widget.Button cannot be cast to android.widget.ImageView
今天遇到一个错误也不知道怎么回事,上网搜了一下: 出现的问题是:java.lang.ClassCastException:android.widget.Button cannot be cast to ...
- switch()出现警告warning:enumeration value ‘xxx’ not handled in switch
enumeration value ... not handled in switch 如果在switch中使用使用枚举类型,如:switch(枚举类型) 枚举类型的个数没有全部列出,就会报这个警告
- ubuntu 下交叉编译环境的搭建
1. 安装标准的C开发环境,由于Linux安装默认是不安装的,所以需要先安装一下(如果已经安装好的话,就可以免去这一步了): #sudo apt-get install gcc g++ libgcc1 ...
- web API请求与参数获取
总结webAPI的常用请求方法与后台参数的获取: 一:get请求:(会将所以参数拼接到URL里面) 1:基础类型:string a=“hello” , 前端无论你是写到ajax里面的data属性还是 ...