这题有点难度
不多说,上代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
unsigned int h[500000],pow[500000];
char st[500000];
int f[500000],n,l0[500000],r0[500000];
void hs_make(char st[],unsigned int h[])
{
pow[0]=1;
for(int i=1;i<=strlen(st);i++)h[i]=h[i-1]*233+st[i-1]-48,pow[i]=pow[i-1]*233;
}
unsigned int hs(int l,int r){return h[r]-h[l-1]*pow[r-l+1];}
int xy(int l1,int r1,int l2,int r2)
{
if(r1-l1+1<r2-l2+1)return 1;
if(r1-l1+1>r2-l2+1)return 0;
int l=0,r=r1-l1+1,mid;
while(l<r)
{
mid=(l+r+1)>>1;
if(hs(l1,l1+mid-1)==hs(l2,l2+mid-1))l=mid;
else r=mid-1;
}
return l!=r1-l1+1&&st[l1+l-1]<st[l2+l-1];
}
struct Segment_tree
{
int a[200000],tag[200000];
void build(int rot,int lt,int rt)
{
tag[rot]=a[rot]=0;
if(lt==rt)return;
int mid=(lt+rt)>>1;
build(rot<<1,lt,mid),build(rot<<1|1,mid+1,rt);
}
void pushdown(int rot,int lt,int rt)
{
if(tag[rot])
{
int t=tag[rot];tag[rot]=0;
tag[rot<<1]=max(t,tag[rot<<1]),tag[rot<<1|1]=max(t,tag[rot<<1|1]);
a[rot<<1]=max(t,a[rot<<1]),a[rot<<1|1]=max(t,a[rot<<1|1]);
}
}
int query(int rot,int lt,int rt,int q)
{
if(lt==rt)return a[rot];
int mid=(lt+rt)>>1;
pushdown(rot,lt,rt);
if(q<=mid)return query(rot<<1,lt,mid,q);
else return query(rot<<1|1,mid+1,rt,q);
}
void update(int rot,int lt,int rt,int lq,int rq,int w)
{
if(lt>rq||rt<lq)return;
if(lt>=lq&&rt<=rq)
{
a[rot]=max(a[rot],w),tag[rot]=max(tag[rot],w);
return;
}
int mid=(lt+rt)>>1;
pushdown(rot,lt,rt);
update(rot<<1,lt,mid,lq,rq,w),update(rot<<1|1,mid+1,rt,lq,rq,w);
a[rot]=max(a[rot<<1],a[rot<<1|1]);
}
}seg;
int main()
{
while(scanf("%s",st)==1)
{
hs_make(st,h);n=strlen(st);
for(int i=1;i<=n;i++)if(st[i-1]=='0')l0[i]=l0[i-1];else l0[i]=i;r0[n+1]=n+1;
for(int i=n;i>=1;i--)if(st[i-1]=='0')r0[i]=r0[i+1];else r0[i]=i;
seg.build(1,0,n);
for(int i=0;i<n;i++)
{
int fi=seg.query(1,0,n,i);
int t=r0[i+1]+i-r0[fi];
if(!xy(r0[fi],i,r0[i+1],t))t++;
if(t<=n)seg.update(1,0,n,t,n,i+1);
}
int fn=seg.query(1,0,n,n);
seg.build(1,0,n);
seg.update(1,0,n,l0[fn-1]+1,n,n);
for(int i=fn;i>1;i--)
{
int fi=seg.query(1,0,n,i);
int t=l0[max(i-1+r0[i]-fi-1,0)]+1;
if(!xy(r0[t],i-1,r0[i],fi))t=r0[t]+1;
seg.update(1,0,n,t,i-1,i-1);
}
int pos=seg.query(1,0,n,1);
for(int i=1;i<=n;i++)
{
putchar(st[i-1]);
if(i==pos&&i!=n)putchar(','),pos=seg.query(1,0,n,i+1);
}
putchar(10);
}
}
//当然,你可以用万能头文件