解题:USACO06DEC Milk Patterns
初见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",<h,&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的更多相关文章
- USACO06DEC Milk Patterns——Solution
题目描述 Farmer John has noticed that the quality of milk given by his cows varies from day to day. On f ...
- [USACO06DEC] Milk Patterns
题目描述 Farmer John has noticed that the quality of milk given by his cows varies from day to day. On f ...
- BZOJ 1717 [USACO06DEC] Milk Patterns (后缀数组+二分)
题目大意:求可重叠的相同子串数量至少是K的子串最长长度 洛谷传送门 依然是后缀数组+二分,先用后缀数组处理出height 每次二分出一个长度x,然后去验证,在排序的后缀串集合里,有没有连续数量多于K个 ...
- luoguP2852 [USACO06DEC]Milk Patterns
题意 显然如果有一个子串出现过\(k\)次,那么它必定是一个至少长为k的后缀序的\(LCP\),求出所有相邻的长为\(k-1\)的\(height\)数组的最小值,在其中取最大值即可 code: #i ...
- [洛谷P2852] [USACO06DEC]牛奶模式Milk Patterns
洛谷题目链接:[USACO06DEC]牛奶模式Milk Patterns 题目描述 Farmer John has noticed that the quality of milk given by ...
- POJ 3261 Milk Patterns 【后缀数组 最长可重叠子串】
题目题目:http://poj.org/problem?id=3261 Milk Patterns Time Limit: 5000MS Memory Limit: 65536K Total Subm ...
- BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 [后缀数组]
1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1017 Solved: ...
- POJ 3261 Milk Patterns 后缀数组求 一个串种 最长可重复子串重复至少k次
Milk Patterns Description Farmer John has noticed that the quality of milk given by his cows varie ...
- 【BZOJ-1717】Milk Patterns产奶的模式 后缀数组
1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 881 Solved: ...
随机推荐
- 「日常训练」Jongmah(Codeforces-1110D)
题意 你有n个数字,范围[1, m],你可以选择其中的三个数字构成一个三元组,但是这三个数字必须是连续的或者相同的,每个数字只能用一次,问这n个数字最多构成多少个三元组? 分析 根据官方Editori ...
- Linux系统中Oracle11g数据库的安装与验证
1.查看Linux系统的位数 2.下载Oracle10g数据库软件 https://blog.csdn.net/xiezuoyong/article/details/81197688 (需要注册Ora ...
- 学习笔记之windows 网络编程
WinSock2.h编程接口笔记在Qtcreater中使用系统默认的库只需要在.pro文件中添加 LIBS += -lws2_32 添加头文件#include <WinSock2.h *初始化套 ...
- vscode中安装使用markdown 插件
linux中好用的IDE vscode是微软推出的一款好用免费的IDE,可以快速部署开发环境,所说配置有些繁琐,但是瑕不掩瑜.它同时支持很多种拓展的编辑器,MarkDown只是其中的一种. 安装 ...
- 利用Tensorflow进行自然语言处理(NLP)系列之二高级Word2Vec
本篇也同步笔者另一博客上(https://blog.csdn.net/qq_37608890/article/details/81530542) 一.概述 在上一篇中,我们介绍了Word2Vec即词向 ...
- [leetcode-915-Partition Array into Disjoint Intervals]
Given an array A, partition it into two (contiguous) subarrays left and right so that: Every element ...
- 把字符串"3,1,2,4"以","分割拆分为数组,数组元素并按从小到大的顺序排列
package com.wangcf; /** * 把字符串"3,1,2,4"以","分割拆分为数组,数组元素并按从小到大的顺序排列 * @author fan ...
- 404 Note Found 现场编程
目录 组员职责分工 github 的提交日志截图 程序运行截图 程序运行环境 GUI界面 基础功能实现 运行视频 LCG算法 过滤(降权)算法 算法思路 红黑树 附加功能一 背景 实现 附加功能二(迭 ...
- whu Problem 1537 - A - Stones I 贪心
题目链接: http://acm.whu.edu.cn/land/problem/detail?problem_id=1537 Stones I Time Limit: 1000MSMemory Li ...
- 第八,九周web制作代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or ...