(HDU 5558) 2015ACM/ICPC亚洲区合肥站---Alice's Classified Message(后缀数组)
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=5558
S[a…b] means a substring of S ranging from S[a] to S[b] (0≤a≤b<N). If the first i letters have been encrypted, Alice will try to find a magic string P. Assuming P has K letters, P is the longest string which satisfies P=S[T...T+K−1] (0≤T<i,T+K≤N) and P=S[i…i+K−1](i+K≤N). In other words, P is a substring of S, of which starting address is within [0...i−1], and P is also a prefix of S[i...N−1]. If P exists, Alice will append integer Kand T to ciphertext. If T is not unique, Alice would select the minimal one. And then i is incremented by K. If P does not exist, Alice will append -1 and the ASCII code of letter S[i] to ciphertext, and then increment i by 1.
Obviously the first letter cannot be encrypted. That is to say, P does not exist when i=0. So the first integer of ciphertext must be -1, and the second integer is the ASCII code of S[0].
When i=N, all letters are encrypted, and Alice gets the final ciphertext, which consists of many pairs of integers. Please help Alice to implement this method.
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <bitset>
using namespace std;
const int N=1e5+;
char s[N];
int wa[N],wb[N],wv[N],wss[N];
int rankk[N],height[N],sa[N];
int cmp(int *r,int a,int b,int l){
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void da(char *r,int *sa,int n,int m)
{
int i,j,p,*x=wa,*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 ;
}
void calheight(char *r,int *sa,int n)
{
int i,j,k=;
for(i=;i<=n;i++) rankk[sa[i]]=i;
for(i=;i<n;height[rankk[i++]]=k)
for(k?k--:,j=sa[rankk[i]-];r[i+k]==r[j+k];k++);
return ;
} int main()
{
int T,Case=;
cin>>T;
while(T--)
{
scanf("%s",s);
int len=strlen(s);
da(s,sa,len+,);
calheight(s,sa,len);
printf("Case #%d:\n",Case++);
int i=;
while(i<len)
{
int pos,k=;
int rk=rankk[i];
int d=height[rk];
for(int j=rk;j>=&&height[j]!=;j--)
{
d=min(d,height[j]);
if(d<k) break;
if(sa[j-]<i&&((d>k)||(d==k&&sa[j-]<pos))) {
k=d; pos=sa[j-];
}
}
if(rk<len){
d=height[rk+];
for(int j=rk+; j<=len&&height[j]!=; j++)
{
d=min(d,height[j]);
if(d<k) break;
if(sa[j]<i&&((d>k)||(d==k&&sa[j]<pos))) {
k=d; pos=sa[j];
}
}
}
if(k) printf("%d %d\n",k,pos),i+=k;
else printf("%d %d\n",-,(int)s[i++]);
}
}
return ;
}
方法二:集合查找
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <bitset>
using namespace std;
const int N=1e5+;
char s[N];
int wa[N],wb[N],wv[N],wss[N];
int cmp(int *r,int a,int b,int l){
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void da(char *r,int *sa,int n,int m)
{
int i,j,p,*x=wa,*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 ;
}
int rankk[N],height[N],sa[N],m[][N];
void calheight(char *r,int *sa,int n)
{
int i,j,k=;
for(int i=;i<=n;i++) rankk[sa[i]]=i;
for(i=;i<n;height[rankk[i++]]=k)
for(k?k--:,j=sa[rankk[i]-];r[i+k]==r[j+k];k++);
return ;
}
set<int>se;
set<int>:: iterator it1,it2; int main()
{
int T,Case=;
cin>>T;
while(T--)
{
scanf("%s",s);
int len=strlen(s);
da(s,sa,len+,);
calheight(s,sa,len);
memset(m,,sizeof(m));
for(int i=;i<=len;i++)
m[][i-]=height[i];
for(int i=;i<=(int)(log(len)/log());i++)
{
for(int j=;j+(<<i)-<=len;j++)
m[i][j]=min(height[j+(<<(i-))],min(m[i-][j],m[i-][j+(<<(i-))]));
}
printf("Case #%d:\n",Case++);
int tot=,minn=-,maxn=;
se.clear();
se.insert(minn);
se.insert(maxn);
while(tot<len)
{
int k=,p;
int pos=tot;
it1=se.upper_bound(rankk[tot]);
it2=it1;
while(*it1!=maxn)
{
int v=(int)(log(*it1-rankk[tot]+)/log());
int f=min(m[v][rankk[tot]],m[v][*it1-(<<v)+]);
if(f<k||f==) break;
if(f>k||(f==k&&sa[*it1]<p)){
k=f;
p=sa[*it1];
}
it1++;
}
it2--;
while(*it2!=minn){
int v=(int)(log(rankk[tot]-*it2+)/log());
int f=min(m[v][*it2],m[v][rankk[tot]-(<<v)+]);
if(f<k||f==) break;
if(f>k||(f==k&&sa[*it2]<p)){
k=f;
p=sa[*it2];
}
it2--;
}
if(k==) {
printf("%d %d\n",-,(int)s[tot]);
tot++;
}
else {
printf("%d %d\n",k,p);
tot+=k;
}
for(;pos<tot;pos++)
se.insert(rankk[pos]);
}
}
return ;
}
(HDU 5558) 2015ACM/ICPC亚洲区合肥站---Alice's Classified Message(后缀数组)的更多相关文章
- HDU 5558 Alice's Classified Message(后缀数组+二分+rmq(+线段树?))
题意 大概就是给你一个串,对于每个\(i\),在\([1,i-1]\)中找到一个\(j\),使得\(lcp(i,j)\)最长,若有多个最大\(j\)选最小,求\(j\)和这个\(lcp\)长度 思路 ...
- HUID 5558 Alice's Classified Message 后缀数组+单调栈+二分
http://acm.hdu.edu.cn/showproblem.php?pid=5558 对于每个后缀suffix(i),想要在前面i - 1个suffix中找到一个pos,使得LCP最大.这样做 ...
- 2015ACM/ICPC亚洲区沈阳站 Pagodas
Pagodas Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- 2015ACM/ICPC亚洲区沈阳站 B-Bazinga
Bazinga Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- hdu 5510 Bazinga (kmp+dfs剪枝) 2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)
废话: 这道题很是花了我一番功夫.首先,我不会kmp算法,还专门学了一下这个算法.其次,即使会用kmp,但是如果暴力枚举的话,还是毫无疑问会爆掉.因此在dfs的基础上加上两次剪枝解决了这道题. 题意: ...
- 2015ACM/ICPC亚洲区沈阳站
5510 Bazinga 题意:给出n个字符串,求满足条件的最大下标值或层数 条件:该字符串之前存在不是 它的子串 的字符串 求解si是不是sj的子串,可以用kmp算法之类的. strstr是黑科技, ...
- 2015ACM/ICPC亚洲区沈阳站 Solution
A - Pattern String 留坑. B - Bazinga 题意:找一个最大的i,使得前i - 1个字符串中至少不是它的子串 思路:暴力找,如果有一个串已经符合条件,就不用往上更新 #inc ...
- HDU 5532 / 2015ACM/ICPC亚洲区长春站 F.Almost Sorted Array
Almost Sorted Array Problem Description We are all familiar with sorting algorithms: quick sort, mer ...
- 2015ACM/ICPC亚洲区沈阳站 部分题解
链接在这:http://bak.vjudge.net/contest/132442#overview. A题,给出a,b和n,初始的集合中有a和b,每次都可以从集合中选择不同的两个,相加或者相减,得到 ...
随机推荐
- 跟vczh看实例学编译原理——零:序言
在<如何设计一门语言>里面,我讲了一些语言方面的东西,还有痛快的喷了一些XX粉什么的.不过单纯讲这个也是很无聊的,所以我开了这个<跟vczh看实例学编译原理>系列,意在科普一些 ...
- 【Prince2是什么】PRINCE2认证之PRINCE2的思维结构
前两讲我们介绍了PRINCE2衡量绩效的六大要素和四大管理步骤,今天我们继续进行PRINCE2思维结构的介绍. PRINCE2自身有一个非常强大且坚固的思维结构,这个结构有四大元素组成.分别是1原则, ...
- iOS 之APP上架
前几天在忙着上线,尽管之前已经上线过一次,但由于本身比较菜,还是状况百出. 好在今天终于成功提交,因此来写写心得. 如果是第一次上线,推荐这篇文章: http://jingyan.baidu.com/ ...
- weblogic配置数据源
启动weblogic 管理服务器,使用管理用户登录weblogic管理控制台 打开管理控制台后,在左侧的树形域结构中,选择服务->数据源. 在右侧的窗口中,选择 新建->一般数据源 ...
- 一个美术需求引发的Custom Inspector
需求 Editor模式下,在运行或者非运行状态下,能够按照指定的变化率来自动改变material中属性数值. 需求分析 如何在Editor模式下获得一个游戏对象及其组件,尤其是在非运行状态下?我们知道 ...
- SQL Server 2014新功能PPT
本篇文章是我在公司内部分享SQL Server 2014新功能的PPT,在本PPT中我详细描述了SQL Server除了BI方面的新功能,以及提供了大量的测试.希望对大家有帮助. 请点 ...
- canvas学习笔记一
为了研究pixi库,就顺带从头到位学习下canvas吧 判断支持力度 var webgl = (function() { try { var canvas = document.createEleme ...
- iTween 动画类型
iTween 动画类型 http://robertpenner.com/easing/easing_demo.html 使用范例 http://www.xuanyusong.com/archives/ ...
- [汇编与C语言关系]3. 变量的存储布局
以下面C程序为例: #include <stdio.h> ; ; ; int c; int main(void) { ; char b[] = "Hello World" ...
- Struts.xml中Action的method与路径的三种匹配方法
原文 http://blog.csdn.net/woshixuye/article/details/7734482 首先我们有一个Action——UserAction public class Us ...