QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#245902#4669. Genetic ModificationsLeasierWA 0ms14020kbC++984.4kb2023-11-10 14:33:082023-11-10 14:33:09

Judging History

你现在查看的是最新测评结果

  • [2023-11-10 14:33:09]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:14020kb
  • [2023-11-10 14:33:08]
  • 提交

answer

#include <stdio.h>
#include <string.h>

#include <vector>

using namespace std;

int pos[100007];
char s[100007], t[100007];
vector<int> sum[100007];
vector<bool> dp[100007];

typedef struct {
	int cnt = 0;
	int type[100007];
	int len[100007];
	
	inline void init(int q, char t[]){
		for (int i = 1; i <= q; ){
			int nxt = i;
			while (nxt < q && t[i] == t[nxt + 1]) nxt++;
			cnt++;
			type[cnt] = t[i] - '0';
			len[cnt] = nxt - i + 1;
			i = nxt + 1;
		}
	}
} String;

String S, T;
int l[100007];

namespace Real {
	typedef struct Segment_tag {
		int l;
		int r;
		
		Segment_tag(){}
		
		Segment_tag(int l_, int r_){
			l = l_;
			r = r_;
		}
		
		inline bool contain(int x){
			return l <= x && x <= r;
		}
	} Segment;
	
	int L = -1, R;
	Segment global;
	int pre[100007][7], nxt[100007][7];
	Segment dp[100007];
	
	Segment operator |(const Segment a, const Segment b){
		if (a.l > a.r) return b;
		if (b.l > b.r) return a;
		return Segment(min(a.l, b.l), max(a.r, b.r));
	}
	
	inline void move(int l, int r){
		if (L < l){
			L = l;
			R = l - 1;
			global = Segment(1e9, 0);
		}
		while (R < r) global = global | dp[++R];
	}
	
	inline void normalize(Segment &seg, int ch){
		if (seg.l > seg.r) return;
		seg.l = nxt[seg.l][ch];
		seg.r = pre[seg.r][ch];
	}
	
	inline void solve(int p, int q){
		for (int i = 1; i <= q; i++){
			for (int j = 0; j <= 1; j++){
				pre[i][j] = t[i] == j + '0' ? i : pre[i - 1][j];
			}
		}
		for (int i = 0; i <= 1; i++){
			nxt[q + 1][i] = q + 1;
		}
		for (int i = q; i >= 1; i--){
			for (int j = 0; j <= 1; j++){
				nxt[i][j] = t[i] == j + '0' ? i : nxt[i + 1][j];
			}
		}
		bool f = true;
		dp[0] = Segment(1e9, 0);
		for (int i = 1; i <= p; i++){
			dp[i] = Segment(1e9, 0);
			if (f && s[i] == t[1]) dp[i] = Segment(1, 1);
			move(max(l[i - 1] - 1, 0), i - 1);
			dp[i] = dp[i] | Segment(global.l + 1, min(global.r + 1, q));
			normalize(dp[i], s[i] - '0');
			f &= s[i] == s[1];
		}
		int ps = p;
		bool flag = true;
		while (ps >= 1){
			if (s[ps] == t[q] && dp[ps].contain(q)) break;
			if (s[ps] != s[p]){
				flag = false;
				break;
			}
			ps--;
		}
		if (ps == 0 || !flag){
			printf("NO");
			return;
		}
		printf("YES\n");
		for (int i = ps, j = q; j >= 1; j--){
			pos[j] = i;
			if (j == 1) break;
			for (int k = i - 1; ; k--){
				if (s[k] == t[j - 1] && dp[k].contain(j - 1)){
					i = k;
					break;
				}
			}
		}
		for (int i = 1; i <= q; i++){
			printf("%d ", pos[i]);
		}
	}
}

int main(){
	scanf("%s %s", &s[1], &t[1]);
	int p = strlen(&s[1]), q = strlen(&t[1]);
	for (int i = 1; i <= p; i++){
		l[i] = s[i] == s[i - 1] ? l[i - 1] : i;
	}
	if (1ll * p * q <= 4e6){
		for (int i = 0; i <= p + 1; i++){
			dp[i].resize(q + 2);
			sum[i].resize(q + 2);
		}
		dp[0][0] = true;
		sum[0][0] = 1;
		for (int i = 1; i <= p + 1; i++){
			sum[i][0] = 1;
			for (int j = 1; j <= q + 1; j++){
				int p = max(l[i - 1] - 1, 0);
				dp[i][j] = s[i] == t[j] && sum[i - 1][j - 1] - (p > 0 ? sum[p - 1][j - 1] : 0) > 0;
				sum[i][j] = sum[i - 1][j] + dp[i][j];
			}
		}
		if (!dp[p + 1][q + 1]){
			printf("NO");
		} else {
			printf("YES\n");
			for (int i = p + 1, j = q; j >= 1; j--){
				for (int k = i - 1; ; k--){
					if (dp[k][j]){
						i = k;
						break;
					}
				}
				pos[j] = i;
			}
			for (int i = 1; i <= q; i++){
				printf("%d ", pos[i]);
			}
		}
	} else {
		bool flag = true;
		for (int i = 1; i < q; i++){
			flag &= t[i] != t[i + 1];
		}
		if (flag){
			S.init(p, s);
			T.init(q, t);
			// one-one
			if (S.cnt == T.cnt){
				if (S.type[1] == T.type[1]){
					int ps = 1;
					printf("YES\n");
					for (int i = 1; i <= S.cnt; i++){
						printf("%d ", ps);
						ps += S.len[i];
					}
					return 0;
				}
			}
			// left left one
			if (S.cnt == T.cnt + 1){
				if (S.type[2] == T.type[1]){
					int ps = S.len[1] + 1;
					printf("YES\n");
					for (int i = 2; i <= S.cnt; i++){
						printf("%d ", ps);
						ps += S.len[i];
					}
					return 0;
				}
			}
			// right left one
			if (S.cnt == T.cnt + 1){
				if (S.type[1] == T.type[1]){
					int ps = 0;
					printf("YES\n");
					for (int i = 1; i <= T.cnt; i++){
						ps += S.len[i];
						printf("%d ", ps);
					}
					return 0;
				}
			}
			printf("NO");
		} else {
			Real::solve(p, q);
		}
	}
	return 0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 12544kb

input:

BBAAABBAAABAAA
BAAB

output:

YES
2 5 8 11 

result:

ok good solution

Test #2:

score: 0
Accepted
time: 0ms
memory: 12944kb

input:

ABABABABAB
ABAB

output:

NO

result:

ok no solution

Test #3:

score: 0
Accepted
time: 0ms
memory: 14020kb

input:

BBAAAAABBAAAAAABBABAABBBBBAABBBAAABABBABABBBAAABBAAAABBBBBABAABBBAABBBBBBBABBABABBAAAABBAAAABAAAABBABAAAAAAABBBBAAAAAABAABABBAAAAABBBBAABABABAAAAABBBABABBAABABBBBAABAABBBBBABBABABBAAABBAAAABBBABBABAAAABBBAABAAABBBAAAAAAAAAAAAABABBAABBBBABABAABBBBABAABBAAABABBBBAAAAAAAABBAAAABBABABABBBAAABAABBABBAAAA...

output:

NO

result:

ok no solution

Test #4:

score: -100
Wrong Answer
time: 0ms
memory: 12948kb

input:

BABABAABABBABAAAAABAABBAAAAABABABBABABBBBBBBAAAAAAABAAAAABAABBABBABABBBABBBAAAABBBABABBAAAABBBAABBBBBBBAAAABAAAABBBBABBAABAABBBAABBBBABAABABBBBAABABBABBAABAABBBBBAAABBAABABBBBAABABBABAABAAAABBABABAABBBABBBBABABABABAAABBABABABABBABAABBBBABAABBABBBBABABBABBBBBAABBBBBAAABAABAAAABBBBBABBABABABBBBABBBABA...

output:

NO

result:

wrong answer you didn't find a solution but jury did