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] ,其中 ...
随机推荐
- Mac系统存储-其他存储无故增大
解决办法:打开Finder:安全倾倒废纸篓就会减少很大一部分存储.
- linux命令学习笔记(51):lsof命令
lsof(list open files)是一个列出当前系统打开文件的工具.在linux环境下,任何事物都以文件的形式存在, 通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件.所以如传输控制协 ...
- 详解C/C++ 编译 g++ gcc 的区别
我们在编译c/c++代码的时候,有人用gcc,有人用g++,于是各种说法都来了,譬如c代码用gcc,而c++代码用g++, 或者说编译用gcc,链 接用g++,一时也不知哪个说法正确,如果再遇上个ex ...
- 华为USG6500系列
华为USG6500: ssh 登录配置 time-range 相关配置:<USG6000V1>system-view Enter system view, return user view ...
- python之系统编程 --进程
1.调试(PDB) 代码: [root@master gaoji]# vim test2.py 1 #!/usr/local/bin/python3 2 # -*- coding:utf-8 -*- ...
- codevs2821 天使之城
传送门 2821 天使之城 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 天使城有一个火车站,每辆火车都从A方向驶入车站 ...
- bzoj 4319 Suffix reconstruction —— 贪心构造
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4319 思维还是不行...这样的构造都没思路... 首先,我们可以按 rank 的顺序从小到大 ...
- Component概念
转自:http://www.cnblogs.com/NEOCSL/archive/2012/05/06/2485227.html 1.总结 Component就是组建的意思,可以在DefaultPro ...
- CS231n 2016 通关 第六章 Training NN Part2
本章节讲解 参数更新 dropout ================================================================================= ...
- Python模块学习——optparse
Python 有两个内建的模块用于处理命令行参数: 一个是 getopt,<Deep in python>一书中也有提到,只能简单处理 命令行参数: 另一个是 optparse,它功能强大 ...