萌新求调
查看原帖
萌新求调
140876
syzf2222楼主2021/8/5 18:29

感觉已经改得和题解差不多了,还是错一片,呜呜呜

求大佬帮忙调,万分感谢

辣鸡syzf的代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 1e9
const int N=2e3+10;
const int K=1e4+10;
const int maxn=1e6+10;
const int mod=1e9+7;
inline int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
int n,m;
string s[N],t[N];
bitset<K>suf[N];
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
pii st[K];int top;
bool f[N][K];
int z[K],p[K];
inline void exkmp(string a,string b){
	int la=a.size(),lb=b.size();
	z[0]=lb;
	for(int i=1,l=0,r=-1;i<lb;i++){
		z[i]=(i<=r?min(z[i-l],r-i+1):0);
		while(i+z[i]<lb&&b[i+z[i]]==b[z[i]])++z[i];
		if(i+z[i]-1>r)l=i,r=i+z[i]-1;
	}
	for(int i=0,l=0,r=-1;i<la;i++){
		p[i]=(i<=r?min(z[i-l],r-i+1):0);
		while(i+p[i]<la&&p[i]<lb&&a[i+p[i]]==b[p[i]])++p[i];
		if(i+p[i]-1>r)l=i,r=i+p[i]-1;
	}
}
inline int cmp(int id,pii a,pii b){
	int flag=1,res=0;
	if(a.fi<b.fi)swap(a,b),flag=-1;
	int x=b.fi,y=a.fi;
	if(x+p[x]<y&&p[x]<=b.se)
		res=(t[id-1][x+p[x]]<s[id][p[x]]?-1:1);
	else if(z[y-x]<a.se&&y-x+z[y-x]<b.se)
		res=(s[id][z[y-x]]<s[id][y-x+z[y-x]]?-1:1);
	return res*flag;
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++)cin>>s[i];
	f[1][0]=f[1][s[1].size()]=1;
	t[1]=s[1];suf[n+1][0]=1;
	for(int i=n;i>=1;i--)
		suf[i]=suf[i+1]|(suf[i+1]<<s[i].size());
	for(int i=2;i<=n;i++){
		int len=s[i].size();
		memset(z,0,sizeof(z));
		exkmp(t[i-1],s[i]);top=0;
		for(int j=0;j<=m;j++){
			if(!suf[i+1][m-j])continue;
			pii cur;
			if(j>=len&&f[i-1][j]&&f[i-1][j-len])
				cur=(cmp(i,mp(j-len,len),mp(j,0))==-1?mp(j-len,len):mp(j,0));
			else if(j>=len&&f[i-1][j-len])cur=mp(j-len,len);
			else if(f[i-1][j])cur=mp(j,0);
			else continue;
			while(top&&cmp(i,cur,st[top])==-1)
				f[i][st[top].fi+st[top].se]=0,top--;
			if(!top||!cmp(i,cur,st[top]))
				st[++top]=cur,f[i][j]=1;
		}
		t[i]=t[i-1].substr(0,st[top].fi)+s[i].substr(0,st[top].se);
	}
	cout<<t[n]<<endl;
    return 0;
}

题解的代码:

#include <bits/stdc++.h>

template <typename T> inline void rd(T& x) {
	int si = 1; char c = getchar(); x = 0;
	while(!isdigit(c)) si = c == '-' ? -1 : si, c = getchar();
	while(isdigit(c)) x = x * 10 + c - 48, c = getchar();
	x *= si;
}
template <typename T, typename... Args>
inline void rd(T& x, Args&... args) { rd(x); rd(args...); }
#define fi first
#define se second
#define mkp std::make_pair
typedef long long ll;
typedef double ff;
typedef std::pair <int, int> pii;
const int N = 2e3 + 5, K = 1e4 + 5, Inf = 0x3f3f3f3f;

void ZAlgo(const std::string &s, int z[]) {
	z[0] = s.size();
	for(int i = 1, l = 0, r = -1; i < s.size(); ++i) {
		z[i] = i <= r ? std::min(z[i - l], r - i + 1) : 0;
		for(; i + z[i] < s.size() && s[i + z[i]] == s[z[i]]; ++z[i]);
		if(i + z[i] - 1 > r) l = i, r = i + z[i] - 1;
	}
}
void ZAlgo(const std::string &s, const std::string &t, int z[], int p[]) {
	ZAlgo(s, z);
	for(int i = 0, l = 0, r = -1; i < t.size(); ++i) {
		p[i] = i <= r ? std::min(z[i - l], r - i + 1) : 0;
		for(; i + p[i] < t.size() && p[i] < s.size() && t[i + p[i]] == s[p[i]]; ++p[i]);
		if(i + p[i] - 1 > r) l = i, r = i + p[i] - 1;
	}
}

int n, k, top, z[K], p[K]; bool f[N][K]; pii st[K];
std::string s[N], t[N];
std::bitset <K> suf[N];

int Comp(int idx, pii A, pii B) {
	int si = 1, x, y, w, ret = 0;
	if(A.fi < B.fi) std::swap(A, B), si *= -1;
	x = B.fi; y = A.fi;
	if(x + p[x] < y && p[x] < B.se)
		ret = t[idx - 1][x + p[x]] < s[idx][p[x]] ? -1 : 1;
	else if(z[y - x] < A.se && y - x + z[y - x] < B.se)
		ret = s[idx][z[y - x]] < s[idx][y - x + z[y - x]] ? -1 : 1;
	return ret * si;
}
void Calc() {
	t[1] = s[1]; f[1][0] = f[1][s[1].size()] = true;
	for(int i = 2; i <= n; ++i) {
		int len = s[i].size();
		memset(z, 0, sizeof(z));
		ZAlgo(s[i], t[i - 1], z, p); top = 0;
		for(int j = 0; j <= k; ++j) if(suf[i + 1][k - j]) {
			pii cur;
			if(j >= len && f[i - 1][j] && f[i - 1][j - len])
				cur = Comp(i, mkp(j - len, len), mkp(j, 0)) == -1 ? mkp(j - len, len) : mkp(j, 0);
			else if(j >= len && f[i - 1][j - len]) cur = mkp(j - len, len);
			else if(f[i - 1][j]) cur = mkp(j, 0);
			else continue;
			for(; top && Comp(i, cur, st[top]) == -1; --top)
				f[i][st[top].fi + st[top].se] = false;
			if(!top || !Comp(i, cur, st[top])) {
				st[++top] = cur;
				f[i][j] = true;
			}
		}
		t[i] = t[i - 1].substr(0, st[top].fi) + s[i].substr(0, st[top].se);
	}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
#endif
	int test_case_cnt = 1; //rd(test_case_cnt);
	while(test_case_cnt--) {
		//std::ios::sync_with_stdio(false);
		std::cin >> n >> k;
		for(int i = 1; i <= n; ++i)
			std::cin >> s[i];
		suf[n + 1][0] = 1;
		for(int i = n; i; --i)
			suf[i] = suf[i + 1] | (suf[i + 1] << s[i].size());
		Calc();
		std::cout << t[n] << std::endl;
	} return 0;
}

感觉都一模一样了啊

2021/8/5 18:29
加载中...