2016vijos 1-1 兔子的字符串(后缀数组 + 二分 + 哈希)
题意:
给出一个字符串,至多将其划分为n部分,每一部分取出字典序最大的子串ci,最小化 最大的ci
先看一个简化版的问题:
给一个串s,再给一个s的子串t,问能否通过将串划分为k个部分,使t成为划分后的s的字典序最大子串
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; #define N 100001 typedef long long LL; const int base=; int n,m;
char s[N]; int a[N];
int v[N];
int p,q=,k;
int sa[][N],rk[][N];
int h[N]; unsigned long long Pow[N],has[N]; pair<int,int>interval[N]; void mul(int *sa,int*rk,int *SA,int *RK)
{
for(int i=;i<=n;++i) v[rk[sa[i]]]=i;
for(int i=n;i;--i) if(sa[i]>k) SA[v[rk[sa[i]-k]]--]=sa[i]-k;
for(int i=n-k+;i<=n;++i) SA[v[rk[i]]--]=i;
for(int i=;i<=n;++i) RK[SA[i]]=RK[SA[i-]]+(rk[SA[i]]!=rk[SA[i-]] || rk[SA[i]+k]!=rk[SA[i-]+k]);
} void presa()
{
for(int i=;i<=n;++i) v[a[i]]++;
for(int i=;i<=;++i) v[i]+=v[i-];
for(int i=;i<=n;++i) sa[p][v[a[i]]--]=i;
for(int i=;i<=n;++i) rk[p][sa[p][i]]=rk[p][sa[p][i-]]+(a[sa[p][i]]!=a[sa[p][i-]]);
for(k=;k<n;k<<=,swap(p,q)) mul(sa[p],rk[p],sa[q],rk[q]);
} void get_height()
{
int j,k=;
for(int i=;i<=n;++i)
{
j=sa[p][rk[p][i]-];
while(a[i+k]==a[j+k]) k++;
h[rk[p][i]]=k;
if(k) k--;
}
} void prehash()
{
Pow[]=;
for(int i=;i<=n;++i) Pow[i]=Pow[i-]*base;
for(int i=;i<=n;++i) has[i]=has[i-]*base+a[i];
} pair<int,int>select(LL k)
{
int now;
LL sum=;
int l,r;
for(int i=;i<=n;++i)
{
now=interval[i].second-interval[i].first+;
if(sum+now>=k)
{
l=sa[p][i];
r=interval[i].first+k-sum-;
return make_pair(l,r);
}
sum+=now;
}
} unsigned long long get_hash(int l,int r)
{
return has[r]-has[l-]*Pow[r-l+];
} int cmp(pair<int,int>x,pair<int,int>y)
{
if(get_hash(x.first,x.second)==get_hash(y.first,y.second)) return ;
int Lx=x.second-x.first+,Ly=y.second-y.first+;
int l=,r=min(Lx,Ly),mid,tmp=;
while(l<=r)
{
mid=l+r>>;
if(get_hash(x.first,x.first+mid-)==get_hash(y.first,y.first+mid-)) tmp=mid,l=mid+;
else r=mid-;
}
if(tmp<min(Lx,Ly)) return s[x.first+tmp]<s[y.first+tmp] ? - : ;
return Lx<Ly ? - : ;
} bool check(pair<int,int>now)
{
int l=n,r=n,sum=;
while(l>=)
if(cmp(make_pair(l,r),now)==)
{
if(l==r) return false;
r=l;
sum++;
if(sum>m) return false;
}
else l--;
return true;
} void solve()
{
LL l=,r=;
for(int i=;i<=n;++i)
{
interval[i].first=sa[p][i]+h[i];
interval[i].second=n;
r+=interval[i].second-interval[i].first+;
}
LL mid,tmp;
pair<int,int>now;
while(l<=r)
{
mid=l+r>>;
now=select(mid);
if(check(now)) tmp=mid,r=mid-;
else l=mid+;
}
now=select(tmp);
l=now.first; r=now.second;
for(int i=l;i<=r;++i) putchar(s[i]);
} int main()
{
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);
scanf("%d",&m);
scanf("%s",s+);
n=strlen(s+);
for(int i=;i<=n;++i) a[i]=s[i]-'a'+;
presa();
get_height();
prehash();
solve();
}
2016vijos 1-1 兔子的字符串(后缀数组 + 二分 + 哈希)的更多相关文章
- 【BZOJ-4556】字符串 后缀数组+二分+主席树 / 后缀自动机+线段树合并+二分
4556: [Tjoi2016&Heoi2016]字符串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 657 Solved: 274[Su ...
- 【BZOJ4556】[Tjoi2016&Heoi2016]字符串 后缀数组+二分+主席树+RMQ
[BZOJ4556][Tjoi2016&Heoi2016]字符串 Description 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了一 ...
- 【BZOJ3277/3473】串/字符串 后缀数组+二分+RMQ+双指针
[BZOJ3277]串 Description 字符串是oi界常考的问题.现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). Inpu ...
- POJ 2774 后缀数组 || 二分+哈希
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 35607 Accepted: 14 ...
- BZOJ 4556 [Tjoi2016&Heoi2016]字符串 ——后缀数组 ST表 主席树 二分答案
Solution 1: 后缀数组暴力大法好 #include <map> #include <cmath> #include <queue> #include &l ...
- BZOJ 3230: 相似子串( RMQ + 后缀数组 + 二分 )
二分查找求出k大串, 然后正反做后缀数组, RMQ求LCP, 时间复杂度O(NlogN+logN) -------------------------------------------------- ...
- 【bzoj4310】跳蚤 后缀数组+二分
题目描述 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典序最大的那一个 ...
- POJ 1743 [USACO5.1] Musical Theme (后缀数组+二分)
洛谷P2743传送门 题目大意:给你一个序列,求其中最长的一对相似等长子串 一对合法的相似子串被定义为: 1.任意一个子串长度都大于等于5 2.不能有重叠部分 3.其中一个子串可以在全部+/-某个值后 ...
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单 ...
随机推荐
- linux下执行sh脚本,提示Command not found解决办法
1.确保用户对文件有读写及执行权限 oracle@linux-106:~/RMAN/bin> chmod a+x test.sh 2.然后修改文件格式(如果是从winodws搬过来的会显示dos ...
- 「CodeForces - 717E」Paint it really, really dark gray (dfs)
BUPT 2017 summer training (for 16) #1H 题意 每个节点是黑色or白色,经过一个节点就会改变它的颜色,一开始在1节点.求一条路径使得所有点变成黑色. 题解 dfs时 ...
- 自学华为IoT物联网_01 物联网概述
点击返回自学华为IoT物流网 自学华为IoT物联网_01 物联网概述 1. 物联网的概念 百度百科: 物联网(Internet of Things),国内外普遍公认的是MIT Auto-ID中心Ash ...
- 05 Zabbix4.0触发器表达式Trigger expression支持的函数
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 05 Zabbix4.0触发器表达式Trigger expression支持的函数 所有函数返回值 ...
- 【Luogu3732】[HAOI2017]供给侧改革(Trie树)
[Luogu3732][HAOI2017]供给侧改革(Trie树) 题面 洛谷 给定一个纯随机的\(01\)串,每次询问\([L,R]\)之间所有后缀两两之间的\(LCP\)的最大值. 题解 一个暴力 ...
- 【BZOJ5416】【NOI2018】冒泡排序(动态规划)
[BZOJ5416][NOI2018]冒泡排序(动态规划) 题面 BZOJ 洛谷 UOJ 题解 考场推出了就是两个上升子序列,并且最长下降子序列长度不超过\(2\)...然后大力暴力状压\(dp\)混 ...
- 【linux】/dev/null作用和/dev/random
一. /dev/null /dev/null属于字符特殊文件,它属于空设备,是一个特殊的设备文件,它会丢弃一切写入其中的数据,写入它的内容都会永远丢失,而且没有任何可以读取的内容. 我们用file命 ...
- poj1182、hdu1829(并查集)
题目链接:http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: ...
- http://bsideup.blogspot.com/2015/04/spring-boot-thrift-part3.html
Building Microservices with Spring Boot and Apache Thrift. Part 3. Asynchronous services Posted on 4 ...
- poj1637 Sightseeing tour(混合图欧拉回路)
题目链接 题意 给出一个混合图(有无向边,也有有向边),问能否通过确定无向边的方向,使得该图形成欧拉回路. 思路 这是一道混合图欧拉回路的模板题. 一张图要满足有欧拉回路,必须满足每个点的度数为偶数. ...