算是后缀数组的入门题吧。 思路无比简单,要是直接套模板的话应该很容易秒掉。

关于后缀数组看高中神犇的论文就可以学会了

算法合集之《后缀数组——处理字符串的有力工具》

话说这题暴力是可以过了,但是我们在做多校的时候就是用暴力过的,当时还不知道什么是后缀数组。。。

靠着概念纯手敲了几个小时,把建SA,求height,和RMQ的ST算法都复习了一遍,这个东西要是每次都手敲的话真的会死人,尤其是倍增算法基数排序怎么排怎么别扭。自己写的倍增算法又太长,大牛的倍增算法总感觉敲的不顺。

贴个代码做留念。。。

Front compression

Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 1344    Accepted Submission(s): 500

Problem Description
Front compression is a type of delta encoding compression algorithm whereby common prefixes and their lengths are recorded so that they need not be duplicated. For example:

The size of the input is 43 bytes, while the size of the compressed output is 40. Here, every space and newline is also counted as 1 byte.
Given the input, each line of which is a substring of a long string, what are sizes of it and corresponding compressed output?
 
Input
There are multiple test cases. Process to the End of File.
The first line of each test case is a long string S made up of lowercase letters, whose length doesn't exceed 100,000. The second line contains a integer 1 ≤ N ≤ 100,000, which is the number of lines in the input. Each of the following N lines contains two integers 0 ≤ A < B ≤ length(S), indicating that that line of the input is substring [A, B) of S.
 
Output
For each test case, output the sizes of the input and corresponding compressed output.
 
Sample Input
frcode
2
0 6
0 6
unitedstatesofamerica
3
0 6
0 12
0 21
myxophytamyxopodnabnabbednabbingnabit
6
0 9
9 16
16 19
19 25
25 32
32 37
 
Sample Output
14 12
42 31
43 40
 
Author
Zejun Wu (watashi)
 
Source
 
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
#define N 100100 char g[N];
int r[N];
int sa[N];
int scnt[N];
int wa[N],wb[N],wv[N];
int mrank[N];
int h[N],th[N];
int dp[N][22];
int save[N]; int cmp(int gg[],int a,int b,int k)
{
return gg[a]==gg[b] && gg[a+k]==gg[b+k];
} void getsa(int str[],int sa[],int n,int m)
{
int i,j,*x,*y,*t;
x=wa; y=wb;
memset(scnt,0,sizeof(scnt));
for(i=0;i<n;i++)
scnt[ x[i]=str[i] ]++;
for(i=1;i<m;i++)
scnt[i]+=scnt[i-1];
for(i=0;i<n;i++)
sa[ --scnt[ str[i] ] ]=i; for(int p=1,j=1;p<n;j*=2,m=p)
{
for(p=0,i=n-j;i<n;i++) y[p++]=i;
for(i=0;i<n;i++) if( sa[i]>=j ) y[p++]=sa[i]-j;
for(i=0;i<n;i++) wv[i]=x[ y[i] ];
memset(scnt,0,sizeof(scnt));
for(i=0;i<n;i++) scnt[ wv[i] ]++;
for(i=1;i<m;i++) scnt[i]+=scnt[i-1];
for(i=n-1;i>=0;i--) sa[ --scnt[ wv[i] ] ] = y[i];
for(p=1,t=x,x=y,y=t,x[sa[0]]=0,i=1;i<n;i++)
x[ sa[i] ] = cmp(y,sa[i],sa[i-1],j)?p-1:p++;
}
} void geth(int str[],int n)
{
h[n-1]=0;
int p=0;
for(int i=0;i<n-1;i++)
{
int tmp=mrank[i];
while( str[i+p] == str[ sa[tmp-1]+p ] ) p++;
h[i]=p;
p--;
p=max(0,p);
}
} void buildst(int n)
{
for(int i=1;i<=n;i++)
dp[i][0] = th[i];
for(int i=1;(1<<i)<=n;i++)
{
for(int j=1;j<=n;j++)
{
if( j+(1<<(i-1)) >n ) dp[j][i]=dp[j][i-1];
else dp[j][i]=min(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
}
}
} int cal(int x,int y)
{
if(x>y) swap(x,y);
x++;
//然后就是求x到y的最小值
int k=0;
while( (1<<k)<=(y-x+1) ) k++;
k--;
return min(dp[x][k],dp[y-(1<<k)+1][k]);
} int main()
{
while(scanf("%s",g)!=EOF)
{
int len=strlen(g);
for(int i=0;i<len;i++)
r[i]=g[i];
r[len++]=0;
getsa(r,sa,len,300);
for(int i=0;i<len;i++)
mrank[ sa[i] ]=i;
//for(int i=0;i<len;i++) printf("%s\n",g+sa[i]);
geth(r,len);
for(int i=0;i<len-1;i++)
th[ mrank[i] ]= h[i];
buildst(len-1);
int m;
long long ans1=0,ans2=0;
scanf("%d",&m);
int x,y,tmp;
scanf("%d%d",&x,&y);
ans1+=y-x; ans2+=y-x; save[1]=0; for(int i=2;i<=m;i++)
{
int tx,ty;
scanf("%d%d",&tx,&ty);
ans1+=ty-tx;
int cnt;
if(tx==x)
cnt=len-1-tx;
else
cnt=cal(mrank[tx],mrank[x]); save[i]=min(ty-tx,min(y-x,cnt));
ans2+=ty-tx-save[i];
x=tx; y=ty;
}
ans1+=m;
ans2+=m+m;
for(int i=1;i<=m;i++)
{
ans2++;
save[i]/=10;
while(save[i])
{
ans2++;
save[i]/=10;
}
}
cout<<ans1<<" "<<ans2<<endl;
}
return 0;
}

  

hdu4691(后缀数组)的更多相关文章

  1. hdu4691 Front compression ——暴力 || 后缀数组

    link:http://acm.hdu.edu.cn/showproblem.php?pid=4691 暴力,数据明显太水了吧,n=10^5, O(n^2)的复杂度哎喂.想让大家暴力写直接让n=100 ...

  2. HDU-4691 Front compression 后缀数组

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4691 后缀数组模板题,求出Height数组后,对Height做RMQ,然后直接统计就可以了... // ...

  3. hdu4691 Front compression(后缀数组)

    Front compression Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) ...

  4. hdu 4691 最长的共同前缀 后缀数组 +lcp+rmq

    http://acm.hdu.edu.cn/showproblem.php? pid=4691 去年夏天,更多的学校的种族称号.当时,没有后缀数组 今天将是,事实上,自己的后缀阵列组合rmq或到,但是 ...

  5. 后缀数组的倍增算法(Prefix Doubling)

    后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...

  6. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  7. BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]

    1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1383  Solved: 582[Submit][St ...

  8. POJ3693 Maximum repetition substring [后缀数组 ST表]

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9458   Acc ...

  9. POJ1743 Musical Theme [后缀数组]

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 27539   Accepted: 9290 De ...

随机推荐

  1. classloader常见问题总结

    h tp://yourenyouyu2008.iteye.com/blog/779707看到一些ClassNoFindException ,ClassCastException等异常首先应该想到是不是 ...

  2. linux任务计划cron

    linux任务计划cron 1.crontab命令任务计划配置文件 [root@bogon ~]# cat /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/ ...

  3. WCF实现客户端和服务端

    service side 1.定义ServiceContract: 2.new a ServiceHost 3. add endpoint using System.ServiceModel; nam ...

  4. Groovy小结:java调用Groovy方法并传递参数

    Groovy小结:java调用Groovy方法并传递参数 @(JAVA总结) 1. 场景描述 在网上查了资料发现,java有三种方式调用groovy脚本.但是真正在实际的服务器环境中,嵌入groovy ...

  5. Request介绍及演示样例 PART1

    Request在ServletAPI的规范连接地址http://blog.csdn.net/zghwaicsdn/article/details/51035146 HTTP简介 URL是浏览器寻找信息 ...

  6. IoC容器Autofac学习笔记

    一.一个没有使用IoC的例子 IoC的全称是Inversion of Control,中文叫控制反转.要理解控制反转,可以看看非控制反转的一个例子. public class MPGMovieList ...

  7. Atitit.提升软件Web应用程序 app性能的方法原理 h5 js java c# php python android .net

    Atitit.提升软件Web应用程序 app性能的方法原理 h5 js java c# php python android .net 1. 提升单例有能力的1 2. 减少工作数量2 2.1. 减少距 ...

  8. Spring Aop基础总结

    什么是AOP: Aop技术是Spring核心特性之中的一个,定义一个切面.切面上包括一些附加的业务逻辑代码.在程序运行的过程中找到一个切点,把切面放置在此处,程序运行到此处时候会运行切面上的代码.这就 ...

  9. rownum浅析

    对于 Oracle 的 rownum 问题,非常多资料都说不支持>.>=.=.between...and,仅仅能用以上符号(<.<=.!=),并不是说用>, >=, ...

  10. apue编程之getopt ,getopt_long使用方法以及实例

    1.getopt 1.1 函数定义 int getopt(int argc, char * const argv[], const char *optstring);#include <unis ...