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

其实这道题的第一个想法是 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. RPI学习--环境搭建_无线网络的连接

    这里不讨论无线网卡的驱动问题,假设内核已经支持了该网卡. 发现命令行下添加无线网络比较麻烦,于是利用图形桌面的工具(WiFi Config)先配置好,在回到字符终端,发现网络已经配置好了 查看内网ip ...

  2. [转]C++运算优先级列表

    From:http://en.cppreference.com/w/cpp/language/operator_precedence Precedence Operator Description A ...

  3. 使用siege进行Web压力测试

    因为最近公司线上node项目出一些不稳定的情况,考虑在这方面能不能做进一步的优化,既然要做优化首先要知道问题出在哪里? 因为暂无法定位是node层问题还是api层出现问题,由于在开发环境小并发量程序运 ...

  4. OpenCV之响应鼠标(二):函数cvSetMouseCallback()和其副程式onMouse()的使用(OpenCV2.4.5)

    每當滑鼠在視訊視窗介面點擊一下的時候,都會有固定三個動作 1.點擊(Click) 2.放開(Down)3.滑動(move) 因此,程式執行滑鼠在點擊的時候onMouse()都會連續跑三次,代表滑鼠在點 ...

  5. 【kate总结】Matlab坐标轴问题

    [kate总结]Matlab坐标轴问题 总结而言 行óYó高ó垂直 列óXó宽ó水平 Maplab中存有2张图片 1.JPG 宽(列):320    高(行):482 在matlab中显示 2.JPG ...

  6. SharePoint 2013 Nintex Workflow 工作流帮助(九)

    博客地址 http://blog.csdn.net/foxdave 前叙:假期结束了,知道为什么假期如此短暂吗?因为假期的每天只有半天.春节过完了,新的一年开始了,大家或许之前在新年的时候都许下了自己 ...

  7. java 集合归类

    对java的集合一直是停留在使用的角度,没有进行系统的归纳,趁现在比较空闲,归纳一下. 1  集合的层次关系 最顶层的有三个集合,其中一个类,两个接口, 一个类是Arrays,两个接口是Collect ...

  8. Cocos2d-x 2.x项目创建

    cocos2d-x下载地址:http://www.cocos2d-x.org/download 2.0之后的创建项目 1. cd cocos2d-x-2.2.1/tools/project-creat ...

  9. Postfix之telnet测试

    1.# 2. 3.#若没安装telnet 需安装telnet 4.yum install telnet 5. 6.#telnet测试smtp连接postfix 7.telnet 127.0.0.1 2 ...

  10. Zipper_DP

    Description Given three strings, you are to determine whether the third string can be formed by comb ...