解题: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: ...
随机推荐
- SteamVR Unity Plugin - v2.0.1中的InteractionSystem
最近写VR项目的时候用到了SteamVR Unity Plugin - v2.0.1插件,感觉比之前用到的SteamVR plugin for Unity - v1.2.2版本改进了很多,就算不用VR ...
- 1.0 Hadoop的介绍、搭建、环境
HADOOP背景介绍 1.1 Hadoop产生背景 HADOOP最早起源于Nutch.Nutch的设计目标是构建一个大型的全网搜索引擎,包括网页抓取.索引.查询等功能,但随着抓取网页数量的增加,遇到了 ...
- Visual Assist 试用期过期怎么办?
Visual Assist 试用期过期怎么办 VS这个强大的编译器常常会配置番茄小助手 Visual Assist,但是有时候试用期会过期,又想免费试用,怎么办呢? 有一个方法可以充值番茄助手的试用期 ...
- eos对数据库的操作
eosio的multi_index 概述 multi_index是eosio上的数据库管理接口,通过eosio::multi_index智能合约能够写入.读取和修改eosio数据库的数据 multi_ ...
- Python3 迭代器和生成器
想要搞明白什么是迭代器,首先要了解几个名词:容器(container).迭代(iteration).可迭代对象(iterable).迭代器(iterator).生成器(generator). 看图是不 ...
- c# apache服务器请求得到数据(初级)
1.代码: string data = new WebClient().DownloadString("http://localhost:81/123.txt");
- Right-BICEP单元测试
一.测试方法:Right-BICEP Right-结果是否正确? B-是否所有的边界条件都是正确的? I-能查一下反向关联吗? C-能用其他手段交叉检查一下结果吗? E-你是否可以强制错误条件发生? ...
- 软件工程 - 第二十次作业 Alpha 事后诸葛亮(团队)
Alpha 事后诸葛亮(团队) 组长本次作业链接:https://www.cnblogs.com/dawnduck/p/10056026.html 现代软件工程 项目Postmortem 设想和目标 ...
- java锁有哪些类(转)
转载来源:http://www.cnblogs.com/lxmyhappy/p/7380073.html 1.Java都有哪些锁? 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/ ...
- 第17章 程序管理与SELinux初探
什么是进程 触发任何一个事件时,系统都会将它定义为一个进程,并且给予这个进程一个ID,称为PID,同时依据触发这个进程的用户与相关属性关系,给予这个进程一组有效的权限设置. 进程与程序 进程:执行一个 ...