【BZOJ4310】跳蚤,后缀数组+ST表求LCP+二分答案
Time:2016.05.26
Author:xiaoyimi
转载注明出处谢谢
传送门
思路:
首先要求出不同子串的个数
有这样一个性质
一个串中不同子串的总数=∑(len-height[i]-sa[i])
然后就可以通过二分子串的排名,来判断当前排名的子串是否符合要求
比较任意两子串的排名用RMQ求LCP
还有一个问题就是知道排名,求其串。
这个要从后向前枚举,一个个减去就好
注意:
注意下标的处理和后缀数组自身的性质
代码:
#include<bits/stdc++.h>
#define M 100003
#define LL long long
using namespace std;
int len,k,ans_l,ans_r,ls,rs;LL sum;
int cnt[M],w[M],sa[M],rank[M],tmp[M],id[M],height[M],fa[M][18];
char s[M];
void SA(int len,int up)
{int d=1,p=0,*t=tmp,*rk=rank;for (int i=0;i<len;i++) cnt[rk[i]=w[i]]++;for (int i=1;i<up;i++) cnt[i]+=cnt[i-1];for (int i=len-1;i>=0;i--) sa[--cnt[rk[i]]]=i;for (;;){for (int i=len-d;i<len;i++) id[p++]=i;for (int i=0;i<len;i++)if (sa[i]>=d) id[p++]=sa[i]-d;for (int i=0;i<up;i++) cnt[i]=0;for (int i=0;i<len;i++) cnt[t[i]=rk[id[i]]]++;for (int i=1;i<up;i++) cnt[i]+=cnt[i-1];for (int i=len-1;i>=0;i--) sa[--cnt[t[i]]]=id[i];p=1;swap(t,rk);rk[sa[0]]=0;for (int i=0;i<len-1;i++)if (sa[i]+d<len&&sa[i+1]+d<len&&t[sa[i]]==t[sa[i+1]]&&t[sa[i]+d]==t[sa[i+1]+d])rk[sa[i+1]]=p-1;elserk[sa[i+1]]=p++;if (p==len) break;d<<=1;up=p;p=0;}
}
void Height(int len)
{for (int i=1;i<=len;i++) rank[sa[i]]=i;int k=0,x;for (int i=0;i<len;i++){x=sa[rank[i]-1];k=max(k-1,0);while (w[x+k]==w[i+k]) k++;height[rank[i]]=k;}
}
void Kth(LL x)
{LL t=x;for (int i=1;i<=len;i++)if (t>len-sa[i]-height[i]) t-=len-sa[i]-height[i];else {ls=sa[i];rs=sa[i]+height[i]+t-1;return;}
}
int LCP(int a,int b)
{if (a==b) return len-sa[a];if (a>b) swap(a,b);int k=log2(b-a); return min(fa[a+1][k],fa[b-(1<<k)+1][k]);
}
bool compare(int x1,int y1,int x2,int y2)
{int l1=y1-x1+1,l2=y2-x2+1,lcp=LCP(rank[x1],rank[x2]);if (lcp>=l1) return l1<=l2;else if (lcp>=l2) return 0;else return s[x1+lcp]<=s[x2+lcp];
}
bool check()
{int last=len-1,p=1;for (int i=len-1;i>=0;i--)if (s[i]>s[ls]) return 0;else if (!compare(i,last,ls,rs)){p++;last=i;if (p>k) return 0;}return 1;
}
main()
{scanf("%d",&k);scanf("%s",s);len=strlen(s);for (int i=0;i<len;i++) w[i]=s[i]-'a'+1;SA(len+1,28);Height(len);for (int i=1;i<=len;i++) sum+=len-sa[i]-height[i];for (int i=1;i<=len;i++) fa[i][0]=height[i];for (int j=1;j<=17;j++)for (int i=1;i<=len-(1<<j-1);i++)fa[i][j]=min(fa[i][j-1],fa[i+(1<<j-1)][j-1]);LL l=1,r=sum,mid;while (l<=r){mid=l+r>>1;Kth(mid);if (check()) ans_l=ls,ans_r=rs,r=mid-1;else l=mid+1;} for (int i=ans_l;i<=ans_r;i++) putchar(s[i]);
}
【BZOJ4310】跳蚤,后缀数组+ST表求LCP+二分答案相关推荐
- 后缀数组 ---- 2018~2019icpc焦作H题[后缀数组+st表+二分+单调栈]
题目链接 题目大意: 给出nnn个数,定义f[l,r]f[l,r]f[l,r]表示 区间[l,r][l,r][l,r]的最大值,求所有 子区间的最大值的和,要求相同的子区间只能算一次 比如数列 5 6 ...
- [BZOJ4310]跳蚤-后缀数组-二分答案
跳蚤 Description 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究.首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择 ...
- [luoguP2463] [SDOI2008]Sandy的卡片(后缀数组 + st表)
传送门 很容易想到,题目中的相同是指差分数组相同. 那么可以把差分数组连起来,中间加上一个没有出现过的且字典序小的数 双指针移动,用st表维护height数组中的最小值. 当然用单调队列应该也可以且更 ...
- codefores 204E. Little Elephant and Strings(后缀数组,RMQ求lcp,二分,主席树)
题目链接 E. Little Elephant and Strings time limit per test3 seconds memory limit per test256 megabytes ...
- 主席树 + 后缀数组求LCP + 二分套二分 ---- P4094 [HEOI2016/TJOI2016]字符串
题目链接 题目大意: 解题思路: 设我们的答案为midmidmid(注意这里有坑是[a,b][a,b][a,b]的所有子串和[c,d][c,d][c,d]这个子串的最长lcplcplcp),那么我们会 ...
- 树链剖分 + 后缀数组 - E. Misha and LCP on Tree
E. Misha and LCP on Tree Problem's Link Mean: 给出一棵树,每个结点上有一个字母.每个询问给出两个路径,问这两个路径的串的最长公共前缀. analyse: ...
- 算法学习:后缀数组 height的求取
[前置知识] 后缀数组 [定义] [LCP]全名最长公共前缀,两个后缀之间的最长前缀,以下我们定义 lcp ( i , j ) 的意义是后缀 i 和 j 的最长前缀 [z函数] 函数z [ i ] 表 ...
- ACM模板——线段树树状数组ST表
int bit[maxn],n; void init() {n = maxn;memset(bit,0,sizeof(bit)); } int sum(int i) {int s = 0;while( ...
- 【BZOJ2588】Count on a tree,主席树维护链+ST表求LCA
传送门 写在前面:一天下来就写了两道主席树的题--(codevs上的一道智障天梯不算) 思路: 才知道原来主席树不仅可以通过dfs序维护子树区间,还可以直接维护一条到根的链-- 我们建好主席树后,每次 ...
最新文章
- 图解ElasticSearch 搜索原理
- MYSQL 创建用户1290错误_rhel6 mysql skip-grant-tables 添加用户报错 ERROR 1290
- Python中lambda表达式学习
- Python学习之序列
- 四、深入elasticsearch中文搜索
- 10万奖金!探索图像盲降噪新方式,旷视2022 MegCup炼丹大赛等你来战
- plsql最多可以存多少_银行内部透露:如果有10万块钱,可以都放在余额宝里吗?存银行是不是更好?...
- Java 9 ← 2017,2019 → Java 13 ,来看看Java两年来的变化
- 剑指offer:剪绳子(找规律,贪心算法,动态规划)
- signature=51b3a9ac95339489ef7384c6e21e303f,nginx – Let’s Encrypt的中间证书
- 数论——同余和费马小定理
- View Agent Direct-Connection注册表
- javascript延时调用函数
- 边城工具集:绘图及标注工具
- iPhone Xs和iPhoneXs max 的区别 哪个好
- 去掉Eslint语法检测
- Q-Learning的学习及简单应用
- 5G-NR通信标准介绍
- Mysql 安装与基础
- 工程监测多通道振弦模拟信号采集仪VTN的MODBUS 通讯协议
热门文章
- Vue源码中compiler部分逻辑梳理(内有彩蛋)
- c语言优先级大全,C语言运算符及其优先级汇总表口诀
- sqlite读音_SQLite 数据类型
- java 嵌套类: Nested classes
- leetcode206题:反转链表(迭代或是递归)
- 打开Jupyter Notebook 时报错:EnvironmentLocationNotFound: Not a conda environment:
- opencv读取MATLAB双目标定的结果进行双目校正
- 【word基础知识】如何将论文中的引文标签和参考文献编号自动关联
- 【mysql基础知识】查询当前时间之前5分钟内的数据
- Spark DataFrame小试牛刀