hdu4691(后缀数组)
算是后缀数组的入门题吧。 思路无比简单,要是直接套模板的话应该很容易秒掉。
关于后缀数组看高中神犇的论文就可以学会了
算法合集之《后缀数组——处理字符串的有力工具》
话说这题暴力是可以过了,但是我们在做多校的时候就是用暴力过的,当时还不知道什么是后缀数组。。。
靠着概念纯手敲了几个小时,把建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

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?
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.
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
42 31
43 40
#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(后缀数组)的更多相关文章
- hdu4691 Front compression ——暴力 || 后缀数组
link:http://acm.hdu.edu.cn/showproblem.php?pid=4691 暴力,数据明显太水了吧,n=10^5, O(n^2)的复杂度哎喂.想让大家暴力写直接让n=100 ...
- HDU-4691 Front compression 后缀数组
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4691 后缀数组模板题,求出Height数组后,对Height做RMQ,然后直接统计就可以了... // ...
- hdu4691 Front compression(后缀数组)
Front compression Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) ...
- hdu 4691 最长的共同前缀 后缀数组 +lcp+rmq
http://acm.hdu.edu.cn/showproblem.php? pid=4691 去年夏天,更多的学校的种族称号.当时,没有后缀数组 今天将是,事实上,自己的后缀阵列组合rmq或到,但是 ...
- 后缀数组的倍增算法(Prefix Doubling)
后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]
1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1383 Solved: 582[Submit][St ...
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- POJ1743 Musical Theme [后缀数组]
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ...
随机推荐
- Drupal启动阶段之三:数据库
Drupal在数据库启动阶段仅仅是简单地包含了database.inc文件,然后再注册类加载器: function _drupal_bootstrap_database() { // Initiali ...
- C#指南,重温基础,展望远方!(6)C#类和对象
类是最基本的 C# 类型. 类是一种数据结构,可在一个单元中就将状态(字段)和操作(方法和其他函数成员)结合起来. 类为动态创建的类实例(亦称为“对象”)提供了定义. 类支持继承和多形性,即派生类可以 ...
- emq(centos 7) 使用
配置文件: EMQ 配置文件: /etc/emqttd/emq.conf 插件配置文件: /etc/emqttd/plugins/*.conf 日志文件 日志文件目录: /var/log/emqttd ...
- c#.net调用pdf2swf.exe将pdf文件转换为swf,vs中运行正常,布署IIS服务器部署转换后文字部分为空白
这个是权限问题, 需要在应用程序池中高级设置,将标识改为LocalSystem
- unity, particle play once and destroy
粒子播放一次后销毁: //ref: http://answers.unity3d.com/questions/219609/auto-destroying-particle-system ...
- Python 集合常用方法总结
数据类型:int/str/bool/list/dict/tuple/float/set (set类型天生去重) 一.集合的定义 s = set() #定义空集合 s = {'a','b','c' ...
- Python内置函数之repr()
repr(object) 返回对象的字符串形式. >>> a = 'hello' >>> repr(a) "'hello'" 返回的字符串形式可 ...
- iOS开发多线程篇 05 —GCD介绍
iOS开发多线程篇—GCD介绍 一.简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD的优势 G ...
- Jquery学习笔记(11)--jquery的ajax删除用户,非常简单!
jquery的ajax,简直简单!!只要一个$.get(url,map,function)就搞定了! index.php: <!DOCTYPE html> <html lang=&q ...
- CentOS6.5下Apache防止目录遍历
原先以为CentOS下的Apache应该是默认关闭目录遍历的... 然后拿自己网站试了一下发现想太多...汗 就去改下Apache的配置 首先Apache的配置文件在 /etc/httpd/conf/ ...