后缀数组 --- 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 ...
随机推荐
- iphone/ipad/ipod设置VPN(pptp连接方式)
一.点击桌面上的-设置-图标进入设置(如图) 二.点击-通用-进入通用设置 三.点击-VPN-进入VPN设置(如图) 四.点击添加VPN设置进行设置 五.选择并连接
- 【Python】winpython下的包安装
1.安装easy_install http://blog.csdn.net/A8572785/article/details/10945237 2.与ipython兼容的ipdb命令 pip inst ...
- 火狐 SSL 收到了一个弱临时 Diffie-Hellman 密钥的解决办法
连接 https网址 时发生错误. 在服务器密钥交换握手信息中 SSL 收到了一个弱临时 Diffie-Hellman 密钥. (错误码: ssl_error_weak_server_ephemera ...
- Java历史版本下载
下载个以前版本的Java工具不容易.Java SE 6 版本拿去: http://www.oracle.com/technetwork/java/javasebusiness/downloads/ja ...
- 海蜘蛛WiFiDog固件 MTK7620 OEM,带云AC功能、探针、广告插入,MTK7620解包打包维修默认参数
修改内容: 1.系统默认管理员员帐号密码 2.系统默认LAN 接口地址 3.系统默认DHCP及保留地址 4.系统默认云AC远程地址及协议内容 5.系统默认JS插入地址 6.系统默认探针位置 7.默认顶 ...
- 在Linux下用源码编译安装apache2
Linux下安装一个软件,最好去看下它的官方guide,apache2.4的安装安装guide 0. installation guide http://httpd.apache.org/docs/2 ...
- ASP.NET MVC 获取当前访问域名
var request = filterContext.HttpContext.Request; string url = request.Url.Authority; string function ...
- 图解 & 深入浅出JavaWeb:事务必会必知
事务,大家所熟悉的事务(Transcation),基本上会就往Spring事务靠.其实Spring事务管理基于底层数据库本身的事务处理机制.数据库事务的基础,是掌握Spring事务管理的基础.这篇总结 ...
- Invalid Image Path - No image found at the path referenced under key "CFBundleIconFile": Icon.png
I got the same error when uploading my app. Moving all icon files to the Asset Catalog works if your ...
- Color Me Less
Color Me Less Time Limit: 2 Seconds Memory Limit: 65536 KB Problem A color reduction is a mappi ...