Front compression

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

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
 
Recommend
zhuyuanchen520
 

后缀数组随便搞一下就可以了

 /* ***********************************************
Author :kuangbin
Created Time :2013/8/20 13:40:03
File Name :F:\2013ACM练习\2013多校9\1006.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXN=;
int t1[MAXN],t2[MAXN],c[MAXN];//求SA数组需要的中间变量,不需要赋值
//待排序的字符串放在s数组中,从s[0]到s[n-1],长度为n,且最大值小于m,
//除s[n-1]外的所有s[i]都大于0,r[n-1]=0
//函数结束以后结果放在sa数组中
bool cmp(int *r,int a,int b,int l)
{
return r[a] == r[b] && r[a+l] == r[b+l];
}
void da(int str[],int sa[],int rank[],int height[],int n,int m)
{
n++;
int i, j, p, *x = t1, *y = t2;
//第一轮基数排序,如果s的最大值很大,可改为快速排序
for(i = ;i < m;i++)c[i] = ;
for(i = ;i < n;i++)c[x[i] = str[i]]++;
for(i = ;i < m;i++)c[i] += c[i-];
for(i = n-;i >= ;i--)sa[--c[x[i]]] = i;
for(j = ;j <= n; j <<= )
{
p = ;
//直接利用sa数组排序第二关键字
for(i = n-j; i < n; i++)y[p++] = i;//后面的j个数第二关键字为空的最小
for(i = ; i < n; i++)if(sa[i] >= j)y[p++] = sa[i] - j;
//这样数组y保存的就是按照第二关键字排序的结果
//基数排序第一关键字
for(i = ; i < m; i++)c[i] = ;
for(i = ; i < n; i++)c[x[y[i]]]++;
for(i = ; i < m;i++)c[i] += c[i-];
for(i = n-; i >= ;i--)sa[--c[x[y[i]]]] = y[i];
//根据sa和x数组计算新的x数组
swap(x,y);
p = ; x[sa[]] = ;
for(i = ;i < n;i++)
x[sa[i]] = cmp(y,sa[i-],sa[i],j)?p-:p++;
if(p >= n)break;
m = p;//下次基数排序的最大值
}
int k = ;
n--;
for(i = ;i <= n;i++)rank[sa[i]] = i;
for(i = ;i < n;i++)
{
if(k)k--;
j = sa[rank[i]-];
while(str[i+k] == str[j+k])k++;
height[rank[i]] = k;
}
}
int rank[MAXN],height[MAXN];
int RMQ[MAXN];
int mm[MAXN];
int best[][MAXN];
void initRMQ(int n)
{
mm[]=-;
for(int i=;i<=n;i++)
mm[i]=((i&(i-))==)?mm[i-]+:mm[i-];
for(int i=;i<=n;i++)best[][i]=i;
for(int i=;i<=mm[n];i++)
for(int j=;j+(<<i)-<=n;j++)
{
int a=best[i-][j];
int b=best[i-][j+(<<(i-))];
if(RMQ[a]<RMQ[b])best[i][j]=a;
else best[i][j]=b;
}
}
int askRMQ(int a,int b)
{
int t;
t=mm[b-a+];
b-=(<<t)-;
a=best[t][a];b=best[t][b];
return RMQ[a]<RMQ[b]?a:b;
}
int lcp(int a,int b)
{
a=rank[a];b=rank[b];
if(a>b)swap(a,b);
return height[askRMQ(a+,b)];
}
char str[MAXN];
int r[MAXN];
int sa[MAXN];
int A[MAXN],B[MAXN];
int calc(int n)
{
if(n == )return ;
int ret = ;
while(n)
{
ret++;
n /= ;
}
return ret;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%s",str)==)
{
int n = strlen(str);
for(int i = ;i < n;i++)
r[i] = str[i];
r[n] = ;
da(r,sa,rank,height,n,);
for(int i = ;i <= n;i++)
RMQ[i] = height[i];
initRMQ(n);
int k,u,v;
long long ans1 = , ans2 = ;
scanf("%d",&k);
for(int i = ;i < k;i++)
{
scanf("%d%d",&A[i],&B[i]);
if(i == )
{
ans1 += B[i] - A[i] + ;
ans2 += B[i] - A[i] + ;
continue;
}
int tmp ;
if(A[i]!= A[i-])tmp = lcp(A[i],A[i-]);
else tmp = ;
tmp = min(tmp,B[i]-A[i]);
tmp = min(tmp,B[i-]-A[i-]);
ans1 += B[i] - A[i] + ;
ans2 += B[i] - A[i] - tmp + ;
ans2 += ;
ans2 += calc(tmp);
}
printf("%I64d %I64d\n",ans1,ans2);
}
return ;
}

HDU 4691 Front compression (2013多校9 1006题 后缀数组)的更多相关文章

  1. HDU 4681 String(2013多校8 1006题 DP)

    String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Subm ...

  2. hdu 4691 Front compression (后缀数组)

    hdu 4691 Front compression 题意:很简单的,就是给一个字符串,然后给出n个区间,输出两个ans,一个是所有区间的长度和,另一个是区间i跟区间i-1的最长公共前缀的长度的数值的 ...

  3. HDU 4671 Backup Plan (2013多校7 1006题 构造)

    Backup Plan Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total ...

  4. HDU 4691 Front compression(后缀数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4691 题意:给出Input,求出Compressed output.输出各用多少字节. 思路:求后缀数 ...

  5. HDU 4678 Mine (2013多校8 1003题 博弈)

    Mine Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submis ...

  6. HDU 4705 Y (2013多校10,1010题,简单树形DP)

    Y Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submiss ...

  7. HDU 4704 Sum (2013多校10,1009题)

    Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submi ...

  8. HDU 4699 Editor (2013多校10,1004题)

    Editor Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Su ...

  9. HDU 4696 Answers (2013多校10,1001题 )

    Answers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total S ...

随机推荐

  1. 程序调试命令gdb

    锁定线程 set scheduler-locking 1.要使用此命令,先用gcc -g编译程序,如:  $gcc -g test.c -o test  编译test.c源程序,输入此程序的调试版本t ...

  2. acm专题--并查集

    题目来源:http://hihocoder.com/problemset/problem/1066 #1066 : 无间道之并查集 时间限制:20000ms 单点时限:1000ms 内存限制:256M ...

  3. 进程一些命令pstree,ps,pstack,top

    1. pstree pstree以树结构显示进程$ pstree -p work | grep adsshd(22669)---bash(22670)---ad_preprocess(4551)-+- ...

  4. leetcode 之Longest Consecutive Sequence(六)

    这题要仔细体会下哈希表的用法,要注意的是数组本身是无序的,因此需要向左右进行扩张. 另外这个思路可以进行聚类,把连续的标记为一类. int longestConsecutive(const vecto ...

  5. Delphi XE增强的RTTI妙用--动态创建包中的窗口类

    以前要在运行时创建package中的form类,必须要在form单元文件中这样注册类: Initialization  RegisterClass(TForm3);Finalization  UnRe ...

  6. 20165301 预备作业二:学习基础和C语言基础调查

    <做中学>读后感及C语言学习调查 读<做中学>有感 娄老师在文章中多次提到「做中学(Learning By Doing)」的概念,并通过娄老师自己的减肥经历.五笔练习经历.乒乓 ...

  7. ajax刷新输出实时数据

    setInterval('shuaxin()',3000); function shuaxin(){ $.ajax({//股票 url:"http://apimarkets.wallstre ...

  8. C#矩形框沿直线移动

    C#中用GDT+的一系列方式,可以绘制各种图形:点,直线,圆形,矩形...... C#中这些图形的绘制,一般教程的demo中给出的代码,是在Form1_Paint(object sender, Pai ...

  9. 分子量(UVa1586)

    题目具体描述见:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=830&a ...

  10. 回文词(UVa401)

    详细题目描述见:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_prob ...