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. navigator.geolocation详解

    https://blog.csdn.net/qq_27626333/article/details/51815467 PositionOptions: JSON对象,监听设备位置信息参数 naviga ...

  2. BootStrap的栅格系统的基本写法(布局)

    代码如下: <!DOCTYPE html> <html> <head> <title>BootStrap的基础入门</title> < ...

  3. IDE按住ctrl 打开单元 无效时 的方法

    一般打开单元无效时 是由于程序有错误,若程序没有错误 可以重新build一下 再试. 若实在不行 就右键---open at cursor

  4. LINUX下PHP编译添加相应的动态扩展模块so(不需要重新编译PHP,以openssl.so为例)

    本文转自:原文链接  http://www.cnblogs.com/doseoer/p/4367536.html 网上我看到有很多相关的文章都是简述这个问题的,但毕竟因为LINUX版本众多,很多LIU ...

  5. python 类继承

    #!/usr/bin/python # Filename: inherit.py class SchoolMember: '''Represents any school member.''' def ...

  6. ref:mysql丢失密码,如何修改?

    ref:https://www.linuxidc.com/Linux/2007-05/4338.htm mysql“Access denied for user 'root'@'localhost'” ...

  7. 2017-2018-1 20179202《Linux内核原理与分析》第四周作业

    一.跟踪分析内核的启动过程实验 : 1.启动Menuos: qemu仿真kernel: qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd ...

  8. Python类总结-字段,方法,属性区别及StaticMethod, Property,私有字段和私有属性

    类包含下列 静态属性 动态属性 静态方法 动态方法 class Province: #静态字段--属于类,调用方法类.字段名 memo = "中国23个省之一" #动态字段--属于 ...

  9. 深入浅出Spring(二) IoC详解

    上次的博客深入浅出Spring(一)Spring概述中,我给大家简单介绍了一下Spring相关概念.重点是这么一句:Spring是为了解决企业应用开发的复杂性而创建的一个轻量级的控制反转(IoC)和面 ...

  10. 实验吧--隐写术--九连环--WriteUp

    题目: http://ctf5.shiyanbar.com/stega/huan/123456cry.jpg 是一张图: 放到binwalk查看一下 发现存在压缩文件. 使用-e参数将文件分离 打开文 ...