您的位置:首页 > 其它

bzoj4310: 跳蚤

2016-04-30 09:28 387 查看
二分+后缀数组;

#include<bits/stdc++.h>
#define rep(i,k,n) for(int i=k;i<(n);i++)
#define rep2(i,k,n)for(int i=k;i>=(n);i--)
using namespace std;
const int maxn=100105;
typedef long long ll;
int K,sa[maxn],he[maxn],p1[maxn],p2[maxn],c[maxn],rank[maxn],sig=500,n,rmq[maxn][18],pw[18],Log[maxn],top=0,id[maxn],len;
ll g[maxn];
char s[maxn];
void build_sa(){
int* x=p1;int* y=p2;
rep(i,0,n)c[x[i]=s[i]]++;
rep(i,1,sig)c[i]+=c[i-1];
rep2(i,n-1,0)sa[--c[x[i]]]=i;
for(int h=1;h<=n;h<<1){int t=0;
rep(i,n-h,n)y[t++]=i;rep(i,0,n)if(sa[i]>=h)y[t++]=sa[i]-h;
rep(i,0,sig)c[i]=0;
rep(i,0,n)c[x[y[i]]]++;
rep(i,1,sig)c[i]+=c[i-1];
rep2(i,n-1,0)sa[--c[x[y[i]]]]=y[i];
swap(x,y);t=0;
x[sa[0]]=0;
rep(i,1,n)x[sa[i]]=y[sa[i]]==y[sa[i-1]] && y[sa[i]+h]==y[sa[i-1]+h] ? t : ++t;
t++;if(t>=n)break;
sig=t;
}
rep(i,0,n)rank[sa[i]]=i;
int j=0;
rep(i,0,n){if(!rank[i])continue;
if(j)j--;
int k=sa[rank[i]-1];
while(s[i+j]==s[k+j])j++;
he[rank[i]]=j;
}
}
void init(){pw[0]=1;
rep(i,1,17)pw[i]=pw[i-1]<<1;
rep(i,2,maxn)Log[i]=Log[i>>1]+1;
rep(i,0,n)rmq[i][0]=he[i];
rep(i,1,17)rep(j,0,n)if(j+pw[i-1]<n)rmq[j][i]=min(rmq[j][i-1],rmq[j+pw[i-1]][i-1]); //if(j+pw[i-1]<n)
ll ss=0;
rep(i,0,n){ss+=n-sa[i]-he[i];g[++top]=ss;id[top]=i;}
}
int lcp(int x,int y){if(x==y)return n-x; //
x=rank[x],y=rank[y];
if(x>y)swap(x,y);
int t=Log[y-x];
return min(rmq[x+1][t],rmq[y-pw[t]+1][t]); //
}
int nowl,nowr,ansl,ansr;
void kth(ll k){int t=lower_bound(g+1,g+top+1,k)-g;
nowl=sa[id[t]];nowr=nowl+he[id[t]]+k-g[t-1]-1;len=nowr-nowl+1;
}
bool pan(int l,int r){
int t=min(lcp(l,nowl),min(len,r-l+1));
if(t==r-l+1 && t<=len)return 1;
if(t==len)return 0;
return s[l+t]<=s[nowl+t];
}

bool ok(){int k=0;
int i=n-1,j=n-1;
while(i>=0){
while(j>=0 && pan(j,i))j--;
if(i==j)return 0;
k++;i=j;
}
return (k<=K);
}
int main(){//freopen("in.in","r",stdin);
scanf("%d",&K);
scanf("%s",s);n=strlen(s);
build_sa();
init();
ll l=0,r=g[top];  //
while(l<=r){
ll mid=(l+r)>>1;
kth(mid);
if(ok()){ansl=nowl,ansr=nowr,r=mid-1;}
else l=mid+1;
}
rep(i,ansl,ansr+1)putchar(s[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: