后缀数组搞一下就可以了喵~

其实这道题的第一个想法是 SAM ,建完后缀自动机后拓扑排序跑一遍统计下每个子串的出现次数就 O(N) 就妥妥过掉了

后缀树也是 O(N) 的,统计一下每个节点对应的子树中有多少个叶子节点即可

可是看了一下数据范围,欸呦你妹啊,字符数 1000000+1 是什么心态啊!居然把我的后缀树和后缀 zdj 都卡掉了啊!

然后很痛苦的想了想后缀数组的做法:

搞出 sa, rank, height 三个数组后,跑一遍二分,用一个 tot 表示找到了几个子串

二分答案 L,O(N) 扫个遍如果 height[i]>=L 说明又找到一个子串,tot++,否则重新计算

不过注意这里 tot 的初始值是 1 而不是 0

不过这么个写法怎么写都是 O(NlogN) 的了,如果有更好的写法,请教我做人喵~

#include <cstdio>
#include <cstring>
const int sizeOfN=20002;
const int sizeOfType=1200021; namespace IOspace
{
inline int getint()
{
register int num=0;
register char ch;
do ch=getchar(); while (ch<'0' || ch>'9');
do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9');
return num;
}
inline void putint(int num)
{
char stack[15];
register int top=0;
if (num==0) stack[top=1]='0';
for ( ;num;num/=10) stack[++top]=num%10+'0';
for ( ;top;top--) putchar(stack[top]);
putchar('\n');
}
} int N, K;
int A[sizeOfN]; namespace suffixArray
{
int sa[sizeOfN], rank[sizeOfN], height[sizeOfN]; inline void swap(int *& x, int *& y) {int * t=x; x=y; y=t;}
inline void buildArray()
{
static int t[2][sizeOfN];
static int c[sizeOfType];
int * x=t[0], * y=t[1];
int M=sizeOfType; for (int i=0;i<M;i++) c[i]=0;
for (int i=0;i<N;i++) c[x[i]=A[i]]++;
for (int i=1;i<M;i++) c[i]+=c[i-1];
for (int i=N-1;i>=0;i--) sa[--c[x[i]]]=i; for (int j=0, k=1;j<N;M=j, k<<=1)
{
j=0;
for (int i=N-k;i<N;i++) y[j++]=i;
for (int i=0;i<N;i++) if (sa[i]>=k) y[j++]=sa[i]-k; for (int i=0;i<M;i++) c[i]=0;
for (int i=0;i<N;i++) c[x[y[i]]]++;
for (int i=1;i<M;i++) c[i]+=c[i-1];
for (int i=N-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; swap(x, y);
j=1; x[sa[0]]=0;
for (int i=1;i<N;i++)
x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k]?j-1:j++;
}
}
inline void calcHeight()
{
int l=0;
for (int i=0;i<N;i++) rank[sa[i]]=i;
for (int i=0;i<N;i++)
{
int j=sa[rank[i]-1];
for (l=l?l-1:0;A[i+l]==A[j+l];l++);
height[rank[i]]=l;
}
}
} inline int search(); int main()
{
N=IOspace::getint(), K=IOspace::getint();
for (int i=0;i<N;i++) A[i]=IOspace::getint()+1;
A[N++]=0; suffixArray::buildArray();
suffixArray::calcHeight(); IOspace::putint(search()); return 0;
}
inline bool check(int l)
{
int tot=1;
for (int i=1;i<N;i++)
if (suffixArray::height[i]>=l)
{
if (++tot>=K)
return true;
}
else
tot=1; return false;
}
inline int search()
{
int L=0, R=N, M; while (L+1<R)
{
M=(L+R)>>1;
if (check(M)) L=M;
else R=M;
} return L;
}

机房里把 插入代码(推荐) 给卡了真是 sang xin bing kuang!我要申诉!

[poj 3261]Milk Patterns的更多相关文章

  1. POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)+后缀数组模板

    Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7586   Accepted: 3448 Cas ...

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

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

  3. POJ 3261 Milk Patterns 可重复k次的最长重复子串

    Milk PatternsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=3261 Description ...

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

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

  5. poj 3261 Milk Patterns(后缀数组)(k次的最长重复子串)

    Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7938   Accepted: 3598 Cas ...

  6. POJ 3261 Milk Patterns (后缀数组,求可重叠的k次最长重复子串)

    Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 16742   Accepted: 7390 Ca ...

  7. Poj 3261 Milk Patterns(后缀数组+二分答案)

    Milk Patterns Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk g ...

  8. POJ 3261 Milk Patterns(后缀数组+二分答案)

    [题目链接] http://poj.org/problem?id=3261 [题目大意] 求最长可允许重叠的出现次数不小于k的子串. [题解] 对原串做一遍后缀数组,二分子串长度x,将前缀相同长度超过 ...

  9. 后缀数组 POJ 3261 Milk Patterns

    题目链接 题意:可重叠的 k 次最长重复子串.给定一个字符串,求至少出现 k 次的最长重复子串,这 k 个子串可以重叠. 分析:与POJ 1743做法类似,先二分答案,height数组分段后统计 LC ...

随机推荐

  1. C# Sandboxer

    public static string IsolateCallV1(PageContentHandler pHandler) { string name = Guid.NewGuid().ToStr ...

  2. <转>用thinkPHP实现验证码的功能

    许多系统的登录都有验证码,而如果使用thinkPHP框架搭建网站的话,验证码的生成和验证就比较容易了 1.生成验证码 thinkPHP有对应生成验证码的方法 要使用验证码,需要导入扩展类库中的ORG. ...

  3. Java---NullPoint经验解析

    tv_yue = (TextView) findViewById(R.id.tv_yue); if(!Constant.cf_balance.isEmpty()){ tv_yue.setText(Co ...

  4. iOS开发之吸附动画效果

    步骤:1.使用singleviewapplication创建新的项目 2.在.h文件中创建两张图片的实例对象,并与相关的图片进行相连:创建一个UIDynamicAnimator实例对象 3.在.m文件 ...

  5. ctrl+shift+del 清理火狐缓存,解决页面显示错乱问题

    ctrl+shift+del 清理火狐缓存,解决页面显示错乱问题

  6. Squid代理之反向代理

    (一) 为Internet用户访问企业Web站点提供缓存加速. 1 关闭防火墙

  7. 【LeetCode OJ】Reverse Words in a String

    Problem link: http://oj.leetcode.com/problems/reverse-words-in-a-string/ Given an input string, reve ...

  8. NSArray,NSSet,NSDictionary的遍历,基本使用集锦

    NSArray *array = [NSArray arrayWithObjects:@"zhangsan",@"lisi",@"wangwu&quo ...

  9. 进程同步(二)—— 信号量&内存共享

    内存共享是进程间常用的通信方式,可以实现两个完全独立的进程通信. 在访问共享内存时,同时需要信号量进行访问控制. 使用ipcs -m命令可以查看系统共享内存,ipce -m + key 可以删除指定的 ...

  10. IE6-8支持css3属性

    方法一.让IE6-8支持css3属性 <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/html5shi ...