题面

初见SA

用了一个常见的按$height$分组的操作:二分答案,然后按$height$分组,遇到一个$height$小于$mid$的就丢进下一组并更新答案,如果最多的那组不少于$k$个说明可行

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
int uni[N],num[N],sec[N],bkt[N];
int SA[N],rnk[N],hgt[N];
int n,k,l,r,ans,siz;
void Basenum_Sort()
{
register int i;
for(i=;i<=siz;i++) bkt[i]=;
for(i=;i<=n;i++) bkt[rnk[i]]++;
for(i=;i<=siz;i++) bkt[i]+=bkt[i-];
for(i=n;i;i--) SA[bkt[rnk[sec[i]]]--]=sec[i];
}
void Suffix_Sort()
{
register int i;
int pw=,cnt=;
Basenum_Sort();
while(cnt<n)
{
cnt=;
for(i=;i<=pw;i++) sec[++cnt]=n-pw+i;
for(i=;i<=n;i++) if(SA[i]>pw) sec[++cnt]=SA[i]-pw;
Basenum_Sort(); swap(rnk,sec); rnk[SA[]]=cnt=;
for(i=;i<=n;i++) cnt+=(sec[SA[i-]]!=sec[SA[i]]||sec[SA[i-]+pw]!=sec[SA[i]+pw]),rnk[SA[i]]=cnt;
pw<<=,siz=cnt;
}
}
void Getting_Height()
{
int p=;
for(int i=;i<=n;i++)
if(rnk[i]!=)
{
int r=SA[rnk[i]-];
while(num[r+p]==num[i+p]) p++;
hgt[rnk[i]]=p; if(p>) p--;
}
hgt[]=;
}
bool check(int x)
{
register int i;
int len=,lst=;
for(i=;i<=n;i++)
if(hgt[i]<x)
len=max(i-lst,len),lst=i;
len=max(n-lst+,len);
return len>=k;
}
int main()
{
register int i;
scanf("%d%d",&n,&k);
for(i=;i<=n;i++)
scanf("%d",&num[i]),uni[i]=num[i];
sort(uni+,uni++n),siz=unique(uni+,uni++n)-uni-;
for(i=;i<=n;i++)
rnk[i]=lower_bound(uni+,uni++siz,num[i])-uni,sec[i]=i;
Suffix_Sort(); Getting_Height(); l=,r=n;
while(l<=r)
{
int mid=(l+r)/;
if(check(mid)) ans=mid,l=mid+;
else r=mid-;
}
printf("%d",ans);
return ;
}

Upd:SAM对SA的全面替换已完成

这题丢给SAM就没啥可说的了,直接按定义来就行

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<unordered_map>
#define umap unordered_map
using namespace std;
const int N=;
umap<int,int> trs[N];
int p[N],noww[N],goal[N];
int fth[N],len[N],siz[N];
int rd,lth,kth,cnt,tot,lst,ans;
void Link(int f,int t)
{
noww[++cnt]=p[f];
goal[cnt]=t,p[f]=cnt;
}
void Insert(int ch)
{
int nde=lst,newn=++tot; lst=newn;
siz[newn]=,len[newn]=len[nde]+;
while(nde&&!trs[nde].count(ch))
trs[nde][ch]=newn,nde=fth[nde];
if(!nde) fth[newn]=;
else
{
int tran=trs[nde][ch];
if(len[tran]==len[nde]+)
fth[newn]=tran;
else
{
int rnde=++tot;
len[rnde]=len[nde]+,trs[rnde]=trs[tran];
fth[rnde]=fth[tran],fth[tran]=fth[newn]=rnde;
while(nde&&trs[nde][ch]==tran)
trs[nde][ch]=rnde,nde=fth[nde];
}
}
}
void DFS(int nde)
{
for(int i=p[nde];i;i=noww[i])
DFS(goal[i]),siz[nde]+=siz[goal[i]];
}
int main()
{
register int i;
scanf("%d%d",&lth,&kth),lst=tot=;
for(i=;i<=lth;i++) scanf("%d",&rd),Insert(rd);
for(i=;i<=tot;i++) Link(fth[i],i); DFS();
for(i=;i<=tot;i++)
if(siz[i]>=kth) ans=max(ans,len[i]);
printf("%d",ans);
return ;
}

解题:USACO06DEC Milk Patterns的更多相关文章

  1. USACO06DEC Milk Patterns——Solution

    题目描述 Farmer John has noticed that the quality of milk given by his cows varies from day to day. On f ...

  2. [USACO06DEC] Milk Patterns

    题目描述 Farmer John has noticed that the quality of milk given by his cows varies from day to day. On f ...

  3. BZOJ 1717 [USACO06DEC] Milk Patterns (后缀数组+二分)

    题目大意:求可重叠的相同子串数量至少是K的子串最长长度 洛谷传送门 依然是后缀数组+二分,先用后缀数组处理出height 每次二分出一个长度x,然后去验证,在排序的后缀串集合里,有没有连续数量多于K个 ...

  4. luoguP2852 [USACO06DEC]Milk Patterns

    题意 显然如果有一个子串出现过\(k\)次,那么它必定是一个至少长为k的后缀序的\(LCP\),求出所有相邻的长为\(k-1\)的\(height\)数组的最小值,在其中取最大值即可 code: #i ...

  5. [洛谷P2852] [USACO06DEC]牛奶模式Milk Patterns

    洛谷题目链接:[USACO06DEC]牛奶模式Milk Patterns 题目描述 Farmer John has noticed that the quality of milk given by ...

  6. POJ 3261 Milk Patterns 【后缀数组 最长可重叠子串】

    题目题目:http://poj.org/problem?id=3261 Milk Patterns Time Limit: 5000MS Memory Limit: 65536K Total Subm ...

  7. BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 [后缀数组]

    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1017  Solved: ...

  8. POJ 3261 Milk Patterns 后缀数组求 一个串种 最长可重复子串重复至少k次

    Milk Patterns   Description Farmer John has noticed that the quality of milk given by his cows varie ...

  9. 【BZOJ-1717】Milk Patterns产奶的模式 后缀数组

    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 881  Solved:  ...

随机推荐

  1. Linux系统中Oracle11g数据库的安装与验证

    1.查看Linux系统的位数 2.下载Oracle10g数据库软件 https://blog.csdn.net/xiezuoyong/article/details/81197688 (需要注册Ora ...

  2. JMeter与WireShark

    最近在学习JMeter,刚学了一点皮毛,就掉入了WireShark的坑,我发现在学习的道路上就是不断的给自己挖坑,之前在学习LoadRunner的道路上,遇到的坑更大,就单纯的安装LR就耗费了两个星期 ...

  3. 【坚持】Selenium+Python学习之从读懂代码开始 DAY2

    2018/05/10 [来源:菜鸟教程](http://www.runoob.com/python3/python3-examples.html) #No.1 # 二次方程式 ax**2 + bx + ...

  4. shell基础 -- 入门篇

    shell 英文含义是“壳”,这是相对于内核来说的,shell 也确实就像是内核的壳,通常来说,所有对内核的访问都要经由 shell .同时,shell 还是一门功能强大的编程语言.shell 是 L ...

  5. PytorchZerotoAll学习笔记(三)--自动求导

    Pytorch给我们提供了自动求导的函数,不用再自己再推导计算梯度的公式了 虽然有了自动求导的函数,但是这里我想给大家浅析一下:深度学习中的一个很重要的反向传播 references:https:// ...

  6. 吴恩达 Deep learning 第一周 深度学习概论

    知识点 1. Relu(Rectified Liner Uints 整流线性单元)激活函数:max(0,z) 神经网络中常用ReLU激活函数,与机器学习课程里面提到的sigmoid激活函数相比有以下优 ...

  7. kettle_Spoon 修改共享DB连接带汉字引发的错误

    win10下: kettle_Spoon 修改共享DB连接带汉字引发的错误: Unexpected problem reading shared objects from XML file : nul ...

  8. 为phpStorm 配置PHP_CodeSniffer自动检查代码

    通过composer 安装PHP_CodeSniffer : squizlabs/PHP_CodeSniffer gihub地址 composer global require "squiz ...

  9. 测试与优化bugbugbugbug

    单元测试

  10. Java 学习笔记 ------第二章 从JDK到IDE

    本章学习目标: 了解与设定PATH 了解与指定CLASSPATH 了解与指定SOURCEPATH 使用package与import管理类别 初步认识JDK与IDE的对应关系 一.第一个Java程序 工 ...