1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| constexpr int N=2005,M=1e4+5; inline void zfunc(string b,int z[]) { int n=int(b.length());z[0]=n; for(int i=1,l=0,r=-1;i<n;i++) { z[i]=(i<=r)?min(z[i-l],r-i+1):0; while(i+z[i]<n&&b[i+z[i]]==b[z[i]]) ++z[i]; if(i+z[i]-1>r) l=i,r=i+z[i]-1; } } inline void exkmp(string&a,string&b,int z[],int p[]) { int n=int(a.length()),m=int(b.length()); zfunc(a,z); for(int i=0,l=0,r=-1;i<m;i++) { p[i]=(i<=r)?min(z[i-l],r-i+1):0; while(i+p[i]<m&&p[i]<n&&b[i+p[i]]==a[p[i]])++p[i]; if(i+p[i]-1>r) l=i,r=i+p[i]-1; } } string s[M],t[M];bool g[N][M],f[N][M]; struct dat{int x,y;}st[M];int top=0,p[M],z[M]; inline int cmp(int id,dat a,dat b) { int fl=1,res=0;if(a.x<b.x) swap(a,b),fl*=-1; int x=b.x,y=a.x; if(x+p[x]<y&&p[x]<b.y) res=t[id-1][x+p[x]]<s[id][p[x]]?-1:1; else if(z[y-x]<a.y&&y-x+z[y-x]<b.y) res=s[id][z[y-x]]<s[id][y-x+z[y-x]]?-1:1; return res*fl; } inline void work() { int n,m;cin>>n>>m; for(int i=1;i<=n;i++) cin>>s[i]; g[n+1][0]=true; for(int i=n;i>0;i--) { int l=int(s[i].length()); for(int j=0;j<=m;j++) { if(j>=l) g[i][j]|=g[i+1][j-l]; g[i][j]|=g[i+1][j]; } } t[1]=s[1],f[1][0]=f[1][s[1].length()]=true; for(int i=2;i<=n;i++) { int l=int(s[i].length()); memset(z,0,sizeof(z));memset(p,0,sizeof(p)); exkmp(s[i],t[i-1],z,p);top=0; for(int j=0;j<=m;j++) { if(!g[i+1][m-j]) continue; dat now; if(j>=l&&f[i-1][j]&&f[i-1][j-l]) now=cmp(i,(dat){j-l,l},(dat){j,0})==-1?(dat){j-l,l}:(dat){j,0}; else if(j>=l&&f[i-1][j-l]) now=(dat){j-l,l}; else if(f[i-1][j]) now=(dat){j,0}; else continue; while(top&&cmp(i,now,st[top])==-1) f[i][st[top].x+st[top].y]=false,top--; if(!top||!cmp(i,now,st[top])) st[++top]=now,f[i][j]=true; } t[i]=t[i-1].substr(0,st[top].x)+s[i].substr(0,st[top].y); } cout<<t[n]<<endl; }
CPP
|