bzoj 4650(洛谷 1117) [Noi2016]优秀的拆分——枚举长度的关键点+后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4650
https://www.luogu.org/problemnew/show/P1117
和 bzoj2119 股市的预测 一样。
考虑算出每个点往前的 AA 的个数和往后的 BB 的个数,每个点作为 AA 和 BB 分界点的答案累加起来就行。
算一个点开始的 AA 的个数,就是枚举 A 的长度 L ,然后每 L 个分为一段,在段的开头求 LCP 和 LCS ,给合法的位置区间加1就行。
一开始写成 n2 了,还能有 95 分。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int Mn(int a,int b){return a<b?a:b;}
int Mx(int a,int b){return a>b?a:b;}
const int N=6e4+,K=;
int T,n,len,sa[N],rk[N],tp[N],tx[N],ht[N][K],lg[N],bin[K];
int s[N],f[N],g[N]; char ch[N];
void Rsort(int n,int nm)
{
for(int i=;i<=nm;i++)tx[i]=;
for(int i=;i<=n;i++)tx[rk[i]]++;
for(int i=;i<=nm;i++)tx[i]+=tx[i-];
for(int i=n;i;i--)sa[tx[rk[tp[i]]]--]=tp[i];
}
void get_sa(int n)
{
int nm=;
for(int i=;i<=n;i++)tp[i]=i,rk[i]=s[i]+;
Rsort(n,nm);
for(int k=;;k<<=)
{
int tot=;
for(int i=n-k+;i<=n;i++)tp[++tot]=i;
for(int i=;i<=n;i++)
if(sa[i]>k)tp[++tot]=sa[i]-k;
Rsort(n,nm);memcpy(tp,rk,sizeof rk);
nm=; rk[sa[]]=;
for(int i=;i<=n;i++)
{
int u=sa[i]+k,v=sa[i-]+k; if(u>n)u=;if(v>n)v=;
rk[sa[i]]=(tp[sa[i]]==tp[sa[i-]]&&tp[u]==tp[v])?nm:++nm;
}
if(nm==n)break;
}
}
void ht_init(int n)
{
for(int i=;i<=n;i++)lg[i]=lg[i>>]+;
bin[]=;for(int i=;i<=lg[n];i++)bin[i]=bin[i-]<<;
}
void get_ht(int n)
{
for(int i=,k=,j;i<=n;i++)
{
for((k?k--:),j=sa[rk[i]-];i+k<=n&&j+k<=n&&s[i+k]==s[j+k];k++);
ht[rk[i]][]=k;
}
for(int t=;t<=lg[n];t++)
for(int i=;i+bin[t]-<=n;i++)
ht[i][t]=Mn(ht[i][t-],ht[i+bin[t-]][t-]);
}
int qry_ht(int l,int r,bool fx)
{
if(l==r)return fx?sa[l]-n-:n-sa[l]+;
if(l>r)swap(l,r); int d=lg[r-l];
return Mn(ht[l+][d],ht[r-bin[d]+][d]);
}
void add(int x,int k,int *f){for(;x<=len;x+=(x&-x))f[x]+=k;}
int qry(int x,int *f){int ret=;for(;x;x-=(x&-x))ret+=f[x];return ret;}
int main()
{
scanf("%d",&T); ht_init(); s[]=;
while(T--)
{
scanf("%s",ch+);
n=strlen(ch+); len=n*+;
for(int i=,j=len;i<=n;i++,j--)s[i]=s[j]=ch[i]-'a'+;
s[n+]=; get_sa(len); get_ht(len); memset(f,,sizeof f); memset(g,,sizeof g);
for(int L=,lm=n>>,lst=,tmp=L<<;L<=lm;L++,lst=,tmp+=)
for(int i=;i+L<=n;i+=L)
{
int l2=qry_ht(rk[i],rk[i+L],);
int l1=qry_ht(rk[len-i+],rk[len-i-L+],);
int st=Mx(lst+,i-l1+);
int en=i+l2-L;
if(en<st)continue; lst=en;
add(st,,f); add(en+,-,f);
add(st+tmp-,,g); add(en+tmp,-,g);
}
ll ans=;
for(int i=;i<n;i++)
ans+=(ll)qry(i,g)*qry(i+,f);
printf("%lld\n",ans);
}
return ;
}
bzoj 4650(洛谷 1117) [Noi2016]优秀的拆分——枚举长度的关键点+后缀数组的更多相关文章
- 【洛谷1117_BZOJ4650】[NOI2016] 优秀的拆分(哈希_后缀数组_RMQ)
题目: 洛谷1117 分析: 定义把我校某兔姓神犇Tzz和他的妹子拆分,为"优秀的拆分" 随便写个哈希就能有\(95\)分的好成绩-- 我的\(95\)分做法比fei较chang奇 ...
- bzoj 2119 股市的预测——枚举长度的关键点+后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2119 就是找差分序列上中间差 m 的相等的两段. 考虑枚举这样一段的长度 L .可以把序列分 ...
- bzoj 4650 & 洛谷 P1117 优秀的拆分 —— 枚举关键点+后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4650 https://www.luogu.org/problemnew/show/P1117 ...
- 洛谷2408不同字串个数/SPOJ 694/705 (后缀数组SA)
真是一个三倍经验好题啊. 我们来观察这个题目,首先如果直接整体计算,怕是不太好计算. 首先,我们可以将每个子串都看成一个后缀的的前缀.那我们就可以考虑一个一个后缀来计算了. 为了方便起见,我们选择按照 ...
- [BZOJ 3039&洛谷P4147]玉蟾宫 题解(单调栈)
[BZOJ 3039&洛谷P4147]玉蟾宫 Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. ...
- 洛谷P1712 [NOI2016]区间 尺取法+线段树+离散化
洛谷P1712 [NOI2016]区间 noi2016第一题(大概是签到题吧,可我还是不会) 链接在这里 题面可以看链接: 先看题意 这么大的l,r,先来个离散化 很容易,我们可以想到一个结论 假设一 ...
- 【BZOJ4560】[NOI2016]优秀的拆分
[BZOJ4560][NOI2016]优秀的拆分 题面 bzoj 洛谷 题解 考虑一个形如\(AABB\)的串是由两个形如\(AA\)的串拼起来的 那么我们设 \(f[i]\):以位置\(i\)为结尾 ...
- [NOI2016]优秀的拆分&&BZOJ2119股市的预测
[NOI2016]优秀的拆分 https://www.lydsy.com/JudgeOnline/problem.php?id=4650 题解 如果我们能够统计出一个数组a,一个数组b,a[i]表示以 ...
- luogu1117 [NOI2016]优秀的拆分
luogu1117 [NOI2016]优秀的拆分 https://www.luogu.org/problemnew/show/P1117 后缀数组我忘了. 此题哈希可解决95分(= =) 设\(l_i ...
随机推荐
- RabbitMQ脑裂问题解决方案调查
现象: RabbitMQ GUI上显示 Network partition detectedMnesia reports that this RabbitMQ cluster has experien ...
- POJ 1166 暴力搜索 即 枚举
e.... 米还是没有读懂题....T_T ..... e.... 这就是传说中的暴力吗....太血腥了....太暴力了...九重for循环....就这么赤裸裸的AC了.... 水是水了点..但是.. ...
- js 数组复制问题
师兄面试回来问个问题,js中数组怎么复制,工作中没遇到,面试也涨见识 了,他给我说了下,太晚没留心,打早起来研究下,写个dom,来看下 代码如下 <!doctype html> <h ...
- 练习vue(class,style属性)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- spoj8406
题解: 二分+树状数组 记录以下i在当前拍第几 代码: #include<bits/stdc++.h> using namespace std; ; int a[N],f1[N],f2[N ...
- pyqt(一)安装及配置。
一:简介 PyQt实现了一个Python模块集.它有超过300类,将近6000个函数和方法.它是一个多平台的工具包,可以运行在所有主要操作系统上,包括UNIX,Windows和Mac. PyQt采用双 ...
- POJ 3251 Big Square
A quite challenging problem,最终看了题解才写出来,惭愧 /*Sample Input 6 J*J*** ****** J***J* ****** **B*** ****** ...
- Spring Data JPA之@Query注解
比如有个实体类对象,类名为Book,对应数据表的表名为book 1. 一个使用@Query注解的简单例子:占位符?1和?2 @Query(value = "select name,autho ...
- Flash网页mp3播放器代码(3例)
第一款:可以添加多首歌 代码如下:可以添加多首歌曲中间用 | 间隔符号隔开 <EMBED height=20 type=application/x-shockwave-flash plugi ...
- XML解析之JAXP
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...