后缀数组 --- WOj 1564 Problem 1564 - A - Circle
Problem 1564 - A - Circle
Problem's Link: http://acm.whu.edu.cn/land/problem/detail?problem_id=1564
Mean:
给你一个长度不超过1e6的数字串,求第k大的环状数字串的前面那个位置。
analyse:
好吧,我承认这是个水题,比赛的时候sb了,因为原来做过后缀自动机求解字符串的环状最小表示法,所以一直用后缀自动机的知识去套k小表示法,比赛的时候太固执了。
这题就是后缀数组的sa[]数组的运用,sa[i]=k表示的是字符串所有的后缀按字典序排序后,第i个后缀排在第k个。
那么我们只需将数字串复制一遍接在原串后面(环状),对s求一遍后缀数字得到sa数组,然后找到sa<=n的第k个sa,那么sa[i]-1就是答案。
为什么?看这张图:

连接后的字符串我们可以得到2*n个字符串,但是我们只需关心前n个字符串就可,因为后面的n个字符串其实根本没作用,他们只相当于前n个字符串的前缀的重复出现而已。
所以我们只需要找到满足sa[i]<=n的第k个就行,sa[i]-1就是答案。
Time complexity: O(n)
Source code:
// Memory Time
// 1347K 0MS
// by : crazyacking
// 2015-04-20-19.00
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<iostream>
#include<algorithm>
#define MAXN 1000010
#define LL long long
using namespace std;
const int maxn = ;
int Rank[maxn],wb[maxn],wv[maxn],wss[maxn]; bool cmp(int *r,int a,int b,int l)
{
return r[a]==r[b] && r[a+l]==r[b+l];
} void da(int *r,int *sa,int n,int m)
{
int i,j,p,*x=Rank,*y=wb,*t;
for(i=;i<m;i++) wss[i]=;
for(i=;i<n;i++) wss[x[i]=r[i]]++;
for(i=;i<m;i++) wss[i]+=wss[i-];
for(i=n-;i>=;i--)
sa[--wss[x[i]]]=i;
for(j=,p=;p<n;j*=,m=p)
{
for(p=,i=n-j;i<n;i++) y[p++]=i;
for(i=;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=;i<n;i++) wv[i]=x[y[i]];
for(i=;i<m;i++) wss[i]=;
for(i=;i<n;i++) wss[wv[i]]++;
for(i=;i<m;i++) wss[i]+=wss[i-];
for(i=n-;i>=;i--) sa[--wss[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
return;
} char s[maxn];
int r[maxn],sa[maxn];
int main()
{
int n,k;
while(~scanf("%d %d",&n,&k))
{
getchar();
gets(s);
int len = strlen(s),i;
for(int i=len;i<len*;++i) s[i]=s[i-len];
s[len*]='\0';
len=len*;
for(int i=;i<len;++i)
s[i]+='a'-'';
len++;
for(i=; i<len-; i++)
r[i] = s[i]-'a'+;
r[len-] = ;
da(r,sa,len,);
int idx=;
for(int i=;i<len;++i)
{
if(sa[i]+<=n)
{
idx++;
if(idx==k) printf("%d\n",sa[i]!=?sa[i]:n);
}
}
}
return ;
}
#include<cstdio>
#include<vector>
#include<cstring>
#define MAXN 1000010
using namespace std;
int n,k,len,si,now;
char s[MAXN];
vector<int> num;
int GetAns(vector<int>tp,int tk,int l)
{
if(tp.size()== || l==n-) return tp[];
vector<int> cnt[];
si=tp.size();
for(int i=;i<si;++i)
cnt[s[ (tp[i]+l)%n ]-''].push_back(tp[i]);
now=;
while(tk>cnt[now].size())
{
tk-=cnt[now].size();now++;
}
return GetAns(cnt[now],tk,l+);
}
int main()
{
while(~scanf("%d %d",&n,&k))
{
scanf("%s",s);
len=strlen(s);
num.clear();
for(int i=;i<=len;++i) num.push_back(i);
printf("%d\n",GetAns(num,k,));
}
return ;
}
后缀数组 --- WOj 1564 Problem 1564 - A - Circle的更多相关文章
- UVALive - 6856 Circle of digits 后缀数组+二分
题目链接: http://acm.hust.edu.cn/vjudge/problem/82135 Circle of digits Time Limit: 3000MS 题意 把循环串分割成k块,让 ...
- HDU5008 Boring String Problem(后缀数组 + 二分 + 线段树)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5008 Description In this problem, you are given ...
- Gym - 102028H Can You Solve the Harder Problem? (后缀数组+RMQ+单调栈)
题意:求一个序列中本质不同的连续子序列的最大值之和. 由于要求“本质不同”,所以后缀数组就派上用场了,可以从小到大枚举每个后缀,对于每个sa[i],从sa[i]+ht[i]开始枚举(ht[0]=0), ...
- [whu1564]后缀数组
http://acm.whu.edu.cn/land/problem/detail?problem_id=1564 思路:先把串复制一遍,在末尾补个标记,后缀数组跑一下,扫一遍就ok了(过滤后缀在后半 ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- POJ1743 Musical Theme [后缀数组]
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ...
- 【UOJ #35】后缀排序 后缀数组模板
http://uoj.ac/problem/35 以前做后缀数组的题直接粘模板...现在重新写一下模板 注意用来基数排序的数组一定要开到N. #include<cstdio> #inclu ...
- 2016多校联合训练4 F - Substring 后缀数组
Description ?? is practicing his program skill, and now he is given a string, he has to calculate th ...
- (HDU 5558) 2015ACM/ICPC亚洲区合肥站---Alice's Classified Message(后缀数组)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5558 Problem Description Alice wants to send a classi ...
随机推荐
- 每日英语:A New Way to Learn Chinese
Entrepreneur and author ShaoLan Hsueh thinks that English-speakers can start learning to read Chines ...
- mac OSX 上 brew install hive
本文介绍brew install hive并修改默认的metastore存储方案,改Derby数据库为mysql的方法以及可能遇到的问题的解决方案. 1. 通过homebrew安装hive 1 bre ...
- 修改eclipse启动时eclipse使用的jre
eclipse在启动的时候,和环境变量中的jdk不兼容,可以单独制定eclipse运行的jre. 方法: 在eclipse的配置文件里增加-vm参数即可. 打开eclipse目录下的eclipse.i ...
- egit - not authorized
A. To specify credentials individually for each remote Open Git repositories view, open "Remote ...
- (笔记)Linux内核学习(八)之定时器和时间管理
一 内核中的时间观念 内核在硬件的帮助下计算和管理时间.硬件为内核提供一个系统定时器用以计算流逝的时间.系 统定时器以某种频率自行触发,产生时钟中断,进入内核时钟中断处理程序中进行处理. 墙上时间和系 ...
- CLR via C# 提纲
第I部分 CLR基础第1章 CLR的执行模型 31.1 将源代码编译成托管模块 31.2 将托管模块合并成程序集 61.3 加载公共语言运行时 81.4 执行程序集的代码 101.4.1 IL和验证 ...
- 初探Stage3D(二) 了解AGAL
关于本文 本文并无打算事无巨细的介绍一遍AGAL,仅仅是对现有文档的一些理解及汇总,所以请先阅读相参考文档 AGAL概念 参考资料 http://www.adobe.com/devnet/flashp ...
- IIS7.5配置SSL
1,首先需要准备两个证书(CA证书,服务器证书). CA证书由公共的CA机构提供,widnow系统内部已经内置了很多这类证书,如图(日文系统). 服务器证书是导入到IIS里面用的. 2,有了上面的认识 ...
- CAS认证原理图
- 发布FTP服务,防火墙配置
最近需要在Web服务器上发布一下FTP,不想安装Server-U之类的,就用IIS的了,安装好后,发现外网无法连接.经过测试,发现是防火墙的问题. 查找了下关于FTP的资料,ftp server支持两 ...