题目链接

思路 想到了,但是木写对啊....代码 各种bug,写的乱死了....

输出最靠前的,比较折腾...

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <map>
using namespace std;
#define N 501000
#define LL __int64
int sa[N],height[N],rank[N];
int c[N],wa[N],wb[N];
int p[N];
int res[N];
char str[N];
LL sum[N];
LL l,r;
int bin[];
int minz[][N];
int sz[][N];
void build_sa(int s[],int n,int m)
{
int i,j,p,*x = wa,*y = wb;
for(i = ;i < m;i ++)
c[i] = ;
for(i = ;i < n;i ++)
c[x[i] = s[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 = ;
for(i = n-j;i < n;i ++)
y[p++] = i;
for(i = ;i < n;i ++)
if(sa[i] >= j) y[p++] = sa[i] - j;
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];
swap(x,y);
p = ;x[sa[]] = ;
for(i = ;i < n;i ++)
x[sa[i]] = y[sa[i-]] == y[sa[i]]&&y[sa[i-]+j] == y[sa[i]+j]?p-:p++;
if(p >= n) break;
m = p;
}
}
void get_height(int s[],int n)
{
int i,j,k = ;
for(i = ;i <= n;i ++)
rank[sa[i]] = i;
for(i = ;i < n;i ++)
{
if(k) k--;
j = sa[rank[i]-];
while(s[i+k]==s[j+k]) k ++;
height[rank[i]] = k;
}
}
void init(int n)
{
int i,j;
for(i = ; i <= n; i ++)
{
minz[][i] = height[i];
sz[][i] = sa[i];
}
for(i = ; bin[i] <= n; i ++)
{
for(j = ; j + bin[i-] <= n; j ++)
{
minz[i][j] = min(minz[i-][j],minz[i-][j+bin[i-]]);
sz[i][j] = min(sz[i-][j],sz[i-][j+bin[i-]]);
}
}
}
int rmq(int s,int t)
{
s = rank[s];
t = rank[t];
if(s > t) swap(s,t);
s ++;
int k = log((t-s+)*1.0)/log(2.0);
return min(minz[k][s],minz[k][t-bin[k]+]);
}
int rmq1(int s,int t)
{
s = rank[s];
t = rank[t];
if(s > t) swap(s,t);
s ++;
int k = log((t-s+)*1.0)/log(2.0);
return min(sz[k][s],sz[k][t-bin[k]+]);
}
void find(LL k,int n)
{
int str,end,mid,i;
str = ;
end = n;
while(str < end)
{
mid = (str + end + )/;
if(sum[mid] > k)
end = mid - ;
else
str = mid;
}
i = end;
if(sum[end] > k)
{
l = sa[i];
r = sa[i]+k-;
}
else if(k == sum[end])
{
l = sa[i];
r = n-;
}
else
{
i ++;
l = sa[i];
r = sa[i] + k - sum[end] + height[i]-;
}
int len = r-l+;
if(i == n)
{
l ++;
r ++;
return ;
}
if(height[i+] < len)
{
l ++;
r ++;
return ;
}
str = i+;
end = n;
while(str < end)
{
mid = (str + end + )/;
if(rmq(sa[i],sa[mid]) < len)
end = mid - ;
else
str = mid;
}
if(rmq(sa[i],sa[end]) >= len)
{
l = min(l,(LL)rmq1(sa[i],sa[end]));
r = l+len-;
}
l ++;
r ++;
}
int main()
{
int i,len,n;
LL maxz;
for(i = ; i < ; i ++)
bin[i] = <<i;
LL v,k;
while(scanf("%s",str)!=EOF)
{
len = strlen(str);
for(i = ;i < len;i ++)
{
p[i] = str[i]-'a'+;
}
p[len] = ;
build_sa(p,len+,);
get_height(p,len);
init(len);
maxz = ;
for(i = ;i <= len;i ++)
{
maxz += len-sa[i]-height[i];
sum[i] = maxz;
}
scanf("%d",&n);
l = r = ;
for(i = ;i < n;i ++)
{
scanf("%I64d",&v);
// find(v,len);
// printf("%I64d %I64d\n",l,r);
k = (v^l^r)+; if(k > maxz)
{
l = r = ;
}
else
{
find(k,len);
}
printf("%I64d %I64d\n",l,r);
}
}
return ;
}

HDU 5008 Boring String Problem(后缀数组+二分)的更多相关文章

  1. HDU - 5008 Boring String Problem (后缀数组+二分法+RMQ)

    Problem Description In this problem, you are given a string s and q queries. For each query, you sho ...

  2. HDU 5008 Boring String Problem

    题意:给定一个串长度<=1e5,将其所有的不同的字串按照字典序排序,然后q个询问,每次询问字典序第k小的的起始坐标,并且起始坐标尽量小. 分析: 一开始看错题意,没有意识到是求不同的字串中第k小 ...

  3. HDU5008 Boring String Problem(后缀数组)

    练习一下字符串,做一下这道题. 首先是关于一个字符串有多少不同子串的问题,串由小到大排起序来应该是按照sa[i]的顺序排出来的产生的. 好像abbacd,排序出来的后缀是这样的 1---abbacd ...

  4. HDOJ 5008 Boring String Problem

    后缀数组+RMQ+二分 后缀数组二分确定第K不同子串的位置 , 二分LCP确定可选的区间范围 , RMQ求范围内最小的sa Boring String Problem Time Limit: 6000 ...

  5. HDU 3518 Boring counting(后缀数组,字符处理)

    题目 参考自:http://blog.sina.com.cn/s/blog_64675f540100k9el.html 题目描述: 找出一个字符串中至少重复出现两次的字串的个数(重复出现时不能重叠). ...

  6. BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案

    BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单 ...

  7. Poj 1743 Musical Theme(后缀数组+二分答案)

    Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...

  8. BZOJ 3230: 相似子串( RMQ + 后缀数组 + 二分 )

    二分查找求出k大串, 然后正反做后缀数组, RMQ求LCP, 时间复杂度O(NlogN+logN) -------------------------------------------------- ...

  9. 【bzoj4310】跳蚤 后缀数组+二分

    题目描述 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典序最大的那一个 ...

随机推荐

  1. file_get_contents带bom

    $dmText = file_get_contents( AROOT .'data' . DS . 'DMType.json.php'); if(preg_match('/^\xEF\xBB\xBF/ ...

  2. PHP代码获取客户端IP地址经纬度及所在城市

    echo $_SERVER['HTTP_HOST'];//echo $_SERVER['REQUEST_URI'];$getIp=$_SERVER["REMOTE_ADDR"];e ...

  3. python之路十六

    一.什么是DOM?    什么叫DOM,DOM是文档对象模型(Document Object Model,是基于浏览器编程(在本教程中,可以说就是DHTML编程)的一套API接口,W3C出台的推荐标准 ...

  4. VC++/MFC 最常用宏和指令

    1.#include指令  包含指定的文件,最基本的最熟悉的指令,编程中不得不用,包含库文件用双尖括号,包含自定义头文件用双引号. 2.#define指令   预定义,通常用它来定义常量(包括无参量与 ...

  5. linux vim 插入行号

    1 在文本中插入行号 最近有朋友提到某编辑器有一个可以插入行号的插件,问Vim有没有办法可以在文章中插入行号.%$^&*#8~#$@#!--让我们看一下有多少种方式可以在vim中插入行号或数字 ...

  6. 使用keychain保存用户名和密码等敏感信息 KeychainItemWrapper和SFHFKeychainUtils

    iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储.相对于 NSUserDefaults.文件保存等一般方式,ke ...

  7. node的核心模块path

    //导入模块path var path=require("path"); //path.basename :输出文件名+后缀 //console.log(path.basename ...

  8. 可视化日历_Java实现

    //刚刚学Java,写的小程序 package cn.xiaocangtian.testDate; import java.text.DateFormat; import java.text.Pars ...

  9. C语言 遍历流程 变量生命周期

    来自c程序设计 谭浩强 程序编译流程 运行c程序的步骤 在编好一个c程序后.怎样上机进行编译运行呢?一般要经过一下几个步骤: 上机输入和编辑源程序.通过键盘和计算机输入程序,如果发现有错误,要及时改正 ...

  10. python之Socket网络编程

    什么是网络? 网络是由节点和连线构成,表示诸多对象及其相互联系.在数学上,网络是一种图,一般认为专指加权图.网络除了数学定义外,还有具体的物理含义,即网络是从某种相同类型的实际问题中抽象出来的模型.在 ...