1 条题解
-
1
#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; // for(int i=1;i<=n;i++)cout<<l0[i]<<" "<<r0[i]<<endl; 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++; // cout<<i<<" "<<fi<<" "<<t<<endl; if(t<=n)seg.update(1,0,n,t,n,i+1); } // for(int i=1;i<=n;i++)cout<<f[i]<<" ";cout<<endl; int fn=seg.query(1,0,n,n); seg.build(1,0,n);//清树 seg.update(1,0,n,l0[fn-1]+1,n,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; // cout<<i<<" "<<f[i]<<" "<<t<<endl; 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); } }
- 1
信息
- ID
- 1234
- 时间
- 2000ms
- 内存
- 159MiB
- 难度
- 7
- 标签
- 递交数
- 3
- 已通过
- 3
- 上传者