【HDOJ5558】Alice's Classified Message(后缀数组)
题意:给定一个长度为n的下标从0开始的小写字母字符串,每次对于当前的i寻找一个j使得后缀i与后缀j的lcp最大,(j<i)若lcp相同则取较小的
若lcp为0则输出0与当前字符,i自增1,否则输出lcp的值与j,i自增lcp的值,以上过程重复直到i>=n
要求模拟这个过程
n<=1e5,sigma n<=2e6
思路:显然后缀的lcp要用到后缀数组
考虑对于每一个i都直接枚举j不可做,对于rank而言可以预处理出每一段连续的height大于0的起始位置和结束位置,在段中往左右两侧暴力枚举
满足要求的条件为:sa[j]<i,且连续的height的min的值不减
这个暴力扫描的复杂度应该假了(真的吗),但数据卡不掉……
- #include<cstdio>
- #include<cstring>
- #include<iostream>
- #include<algorithm>
- typedef long long ll;
- using namespace std;
- #define N 110000
- #define oo 10000000
- #define MOD 100000073
- char ch[N];
- int n,i,s[N],sa[N],wa[N],wb[N],wc[N],wd[N],height[N],Rank[N],pre[N],nxt[N];
- bool cmp(int *r,int a,int b,int l)
- {
- return r[a]==r[b]&&r[a+l]==r[b+l];
- }
- void getsa(int *r,int *sa,int n,int m)
- {
- int *x=wa,*y=wb,j,p;
- for(i=;i<n;i++) wc[x[i]=r[i]]++;
- for(i=;i<m;i++) wc[i]+=wc[i-];
- for(i=n-;i>=;i--) sa[--wc[x[i]]]=i;
- for(j=,p=;p<n;j*=,m=p)
- {
- p=;
- for(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++) wd[i]=x[y[i]];
- for(i=;i<m;i++) wc[i]=;
- for(i=;i<n;i++) wc[wd[i]]++;
- for(i=;i<m;i++) wc[i]+=wc[i-];
- for(i=n-;i>=;i--) sa[--wc[wd[i]]]=y[i];
- swap(x,y);
- p=; x[sa[]]=;
- for(i=;i<n;i++) x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
- if(j>n) break;
- }
- }
- void getheight(int *r,int *sa,int n)
- {
- int i,j,k=;
- for(i=;i<=n;i++) Rank[sa[i]]=i;
- for(i=;i<n;height[Rank[i++]]=k)
- {
- if(k) k--;
- j=sa[Rank[i]-];
- while(r[i+k]==r[j+k]) k++;
- }
- }
- void init()
- {
- memset(s,,sizeof(s));
- memset(sa,,sizeof(sa));
- memset(wa,,sizeof(wa));
- memset(wb,,sizeof(wb));
- memset(wc,,sizeof(wc));
- memset(wd,,sizeof(wd));
- memset(height,,sizeof(height));
- memset(Rank,,sizeof(Rank));
- }
- int main()
- {
- int cas;
- scanf("%d",&cas);
- for(int v=;v<=cas;v++)
- {
- init();
- printf("Case #%d:\n",v);
- scanf("%s",ch);
- n=strlen(ch);
- for(int i=;i<n;i++) s[i]=ch[i]-'a'+;
- s[n]=;
- getsa(s,sa,n+,);
- getheight(s,sa,n);
- for(int i=;i<=n;i++)
- if(!height[i]) pre[i]=i;
- else pre[i]=pre[i-];
- for(int i=n;i>=;i--)
- if(height[i+]==||i==n) nxt[i]=i;
- else nxt[i]=nxt[i+];
- int i=;
- while(i<n)
- {
- int now=Rank[i];
- int k=;
- int t=i;
- int mn=height[now];
- for(int j=now-;j>=pre[now];j--)
- {
- mn=min(mn,height[j+]);
- if(mn<k) break;
- if(sa[j]<i)
- {
- if(mn>k||mn==k&&sa[j]<t)
- {
- k=mn; t=sa[j];
- }
- }
- }
- if(now+<=nxt[now]) mn=height[now+];
- for(int j=now+;j<=nxt[now];j++)
- {
- mn=min(mn,height[j]);
- if(mn<k) break;
- if(sa[j]<i)
- {
- if(mn>k||mn==k&&sa[j]<t)
- {
- k=mn; t=sa[j];
- }
- }
- }
- if(!k)
- {
- printf("-1 %d\n",ch[i]);
- i++;
- }
- else
- {
- printf("%d %d\n",k,t);
- i+=k;
- }
- }
- }
- return ;
- }
【HDOJ5558】Alice's Classified Message(后缀数组)的更多相关文章
- (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 ...
- HUID 5558 Alice's Classified Message 后缀数组+单调栈+二分
http://acm.hdu.edu.cn/showproblem.php?pid=5558 对于每个后缀suffix(i),想要在前面i - 1个suffix中找到一个pos,使得LCP最大.这样做 ...
- HDU 5558 Alice's Classified Message(后缀数组+二分+rmq(+线段树?))
题意 大概就是给你一个串,对于每个\(i\),在\([1,i-1]\)中找到一个\(j\),使得\(lcp(i,j)\)最长,若有多个最大\(j\)选最小,求\(j\)和这个\(lcp\)长度 思路 ...
- hdu5558 Alice's Classified Message
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=5558 题目: Alice's Classified Message Time Limit: 1 ...
- HDU5558 Alice's Classified Message(合肥区域赛 后缀数组)
当初合肥区域赛的题(现场赛改了数据范围就暴力过了),可惜当初后缀数组算法的名字都没听过,现在重做下. i从1到n - 1,每次枚举rank[i]附近的排名,并记录当起点小于i时的LCP(rank[i] ...
- POJ 2774 Long Long Message 后缀数组
Long Long Message Description The little cat is majoring in physics in the capital of Byterland. A ...
- poj 2774 Long Long Message 后缀数组基础题
Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 24756 Accepted: 10130 Case Time Limi ...
- POJ2774Long Long Message (后缀数组&后缀自动机)
问题: The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes to ...
- POJ2774 Long Long Message —— 后缀数组 两字符串的最长公共子串
题目链接:https://vjudge.net/problem/POJ-2774 Long Long Message Time Limit: 4000MS Memory Limit: 131072 ...
随机推荐
- 【Ecshop】修改处理用户购物车的行为
Ecshop v2.7.3的购物车处理方面在现在看来有比较反用户体验的设计: 用户未登录时加入购物车的商品,在用户登录后会被清空而不是加入到登录用户的购物车中: 用户登录后加入购物车的商品,在退出后会 ...
- JZOJ 4307. 喝喝喝
Description
- kubernetes dashboard permission errors
kubernetes dashboard 的权限错误 warning configmaps is forbidden: User "system:serviceaccount:kube-sy ...
- linux系统下单节点hadoop2的配置
Jdk安装: jdk-7u45-linux-x64.gz cp jdk-7u45-linux-x64.gz /usr/java/ cd /usr/java/ tar -zxvf jdk-7u45-li ...
- Linux程序编辑器
重点回顾:Linux底下的配置文件多为文本文件,故使用vim即可进行设定编辑: vim可视为程序编辑器,可用以编辑shell script,配置文件等,避免打错字 vi为所有unix like的操作系 ...
- ObjectOutputStream和ObjectInputStream的简单使用
使用ObjectOutputStream往文本写内容时,首先在文本里面标记开始,然后是内容,最后加上结束标示.如果想再次往文本里面添加内容的话,就要加在开始标示之后和结束标示之前,不然会读取不到写入的 ...
- JVM内存管理:深入Java内存区域与OOM
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝 ...
- scripts
Shell Script:================================================================ 示例1:[root@server0 ~]# ...
- [译]pandas .at 和.loc速度对比
df.at 一次只能访问一个值. df.loc能够选取多行多列. In [25]: %timeit df.loc[('a', 'A'), ('c', 'C')] 10000 loops, best o ...
- 项目中遇到的ts问题汇总
报错关键词句 报错截图 解决 Declaration of public static field not allowed after declaration of public instance m ...