http://acm.hdu.edu.cn/showproblem.php?pid=4691

留个板子。

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn = 1e5+;
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 sa[maxn];
char s[maxn];
int M[maxn][];
int r[maxn];
int A[maxn],B[maxn];
void RMQ(int n)
{
for(int i=;i<=n;i++) M[i][] = height[i];
for(int j=;(<<j)<=n;j++)
{
for(int i=;(i+(<<j)-)<=n;i++)
{
M[i][j] = min(M[i][j-],M[i+(<<(j-))][j-]);
}
}
}
int ST(int l,int r)
{
int k = ;
while((<<(k+))<=(r-l+)) k++;
return min(M[l][k],M[r-(<<k)+][k]);
}
int lcp(int a,int b)
{
a = Rank[a],b = Rank[b];
if(a>b) swap(a,b);
return ST(a+,b);
}
int cal(int x)
{
int res = ;
if(x==) res++;
while(x)
{
x /= ;
res++;
}
return res;
}
int main()
{
while(scanf("%s",s)!=EOF)
{
int len = strlen(s);
for(int i=;i<len;i++) r[i] = s[i];
r[len] = ;
da(r,sa,Rank,height,len,);
RMQ(len);
long long ans1 = ,ans2 = ;
int T;scanf("%d",&T);
for(int i=;i<=T;i++)
{
scanf("%d %d",&A[i],&B[i]);
if(i==)
{
ans1 += B[i]-A[i]+;
ans2 += B[i]-A[i]+;
continue;
}
int temp = ;
if(A[i]!=A[i-]) temp = lcp(A[i-],A[i]);
else temp = 1e9;
temp = min(temp,B[i]-A[i]);
temp = min(temp,B[i-]-A[i-]);
ans1 += B[i]-A[i]+;
ans2 += B[i]-A[i]-temp+;
ans2 += cal(temp);
}
printf("%I64d %I64d\n",ans1,ans2);
}
return ;
}

HDU 4691的更多相关文章

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

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

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

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

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

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

  4. HDU 4691 正解后缀数组(暴力也能过)

    本来是个后缀数组,考察算法的中级题目,暴力居然也可以水过,就看你跳不跳坑了(c++和G++返回结果就很不一样,关键看编译器) 丝毫不差的代码,就看运气如何了.唯一差别c++还是G++,但正解是后缀数组 ...

  5. hdu 4691 Front compression

    暴力水过,剪一下枝= =果断是数据水了 #include<cstdio> #include<cstring> #include<algorithm> #define ...

  6. HDU 4691(多校第九场1006) 后缀数组

    ...还能多说什么. 眼角一滴翔滑过. 一直以为题意是当前串与所有之前输入的串的LCP...然后就T了一整场. 扫了一眼标程突然发现他只比较输入的串和上一个串? 我心中突然有千万匹草泥马踏过. 然后随 ...

  7. HDU 4691 Front compression (2013多校9 1006题 后缀数组)

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

  8. HDU 4691 后缀数组+RMQ

    思路: 求一发后缀数组,求个LCP 就好了 注意数字有可能不只一位 (样例2) //By SiriusRen #include <bits/stdc++.h> using namespac ...

  9. HDU ACM 2066 一个人的旅行

    一个人的旅行 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

随机推荐

  1. tp5使用外部类的三种方法

    在tp5中使用外部类的时候有三种方法 第一种就是通过composer下载,通过这种方式下载的外部类能够支持自动加载,我们只要在使用的时候use一下命名空间就可以使用了 比如:我们的tp5第四季项目要使 ...

  2. hdu 3836 tarjain 求强连通分量个数

    // 给你一个有向图,问你最少加几条边能使得该图强连通 #include <iostream> #include <cstdio> #include <cstring&g ...

  3. bash之条件测试if/else

    bash之条件测试:     if/then结构         条件测试(CONDITION):         test EXPRESSION:测试条件表达式正确否         [ EXPRE ...

  4. POJ - 1321 深度优先搜索入门

    #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> us ...

  5. tarjan - SPFA - Luogu 3387【模板】缩点

    [模板]缩点 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次 ...

  6. 谋哥:搞APP,做得累的都不对!

    最近谋哥(微信viyi88)我刚加入“秦王会”,思想收到猛烈地冲击,各位大佬的思维有时候会让我大脑短路,收获不少.同时,我也慢慢发现我一直平静的 心开始浮躁,我发现苗头不对,于是开始静下心来.静下心, ...

  7. Hydux: 一个 Elm-like 的 全功能的 Redux 替代品

    在学习和使用 Fable + Elmish 一段时间之后,对 Elm 架构有了更具体的了解, 和预料中的一样,Redux 这种来自 Elm 的风格果然还是和强类型的 Meta Language 语言更 ...

  8. python装饰器实现用户密码认证(简单初形)

    import timecurrent_user={'user':None}def auth(engine = 'file'): def deco(func): #func=最初始的index和最初始的 ...

  9. [转]how to inserting multiple rows in one step

    To insert multiple rows in the table use executemany() method of cursor object. Syntax: cursor_objec ...

  10. spring AOP详解〇

    AOP正在成为软件开发的下一个圣杯.使用AOP,你可以将处理aspect的代码注入主程序,通常主程序的主要目的并不在于处理这些aspect.AOP可以防止代码混乱. 为了理解AOP如何做到这点,考虑一 ...