QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#773835#5312. Levenshtein DistanceyqrRE 0ms19832kbC++143.9kb2024-11-23 10:30:412024-11-23 10:30:41

Judging History

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

  • [2024-11-23 10:30:41]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:19832kb
  • [2024-11-23 10:30:41]
  • 提交

answer

#include<stdio.h>
#include<string.h>
#include<memory.h>
#include<algorithm>
#include<assert.h>
#include <bits/stdc++.h>
using namespace std;
constexpr int maxn = 200005, maxk = 35;
int k, n, m, g[maxk][maxk << 1], ans[maxk];
char s[maxn], t[maxn];
int min(int a, int b) {return a < b? a: b;}
struct SuffixArray {
	int N, V, tmp[maxn << 2], rk[maxn << 1], sa[maxn << 1], cnt[maxn << 1], height[maxn << 1], mn[20][maxn << 1];
	//h[i]=lcp(pre,i)>=h[i-1]-1=lcp(sa[rk[i-1]-1]+1,i-1+1)=lcp(pre_{i-1}+1,i)
	char S[maxn << 1];
	void qsort(int len)
	{
		int num = 0;
		for(int i = N - len + 1; i <= N; i++) tmp[++num] = i;
		for(int i = 1; i <= N; i++) if(sa[i] > len) tmp[++num] = sa[i] - len;
		memset(cnt, 0, sizeof(int) * (V + 5));
		for(int i = 1; i <= N; i++) ++cnt[rk[tmp[i]]];
		for(int i = 1; i <= V; i++) cnt[i] += cnt[i - 1];
		for(int i = N; i; i--) sa[cnt[rk[tmp[i]]]--] = tmp[i];
		memcpy(tmp, rk, sizeof rk);
		num = rk[sa[1]] = 1;
		for(int i = 2; i <= N; i++)
			rk[sa[i]] = tmp[sa[i - 1]] == tmp[sa[i]]
			&& tmp[sa[i - 1] + len] == tmp[sa[i] + len]?
			num: ++num;
		V = num;
	}
	void init()
	{
		for(int i = 1; i <= n; i++) S[i] = s[i];
		S[n + 1] = '#';
		for(int i = 1; i <= m; i++) S[i + n + 1] = t[i];
		V = 256, N = n + 1 + m;
		// puts(S + 1);

		for(int i = 1; i <= N; i++) rk[i] = S[i], sa[i] = i;
		qsort(0);
		for(int L = 1; L <= N; L <<= 1)
		// {
			qsort(L);
			// for(int i = 1; i <= N; i++) printf("%d ", sa[i]);
			// puts("");
		// }

		for(int i = 1; i <= N; i++) assert(rk[sa[i]] == i);

		for(int i = 1, j = 0; i <= N; i++) if(rk[i] > 1)
		{
			if(j) --j;
			int pre = sa[rk[i] - 1];
			while(S[i + j] == S[pre + j]) ++j;
			height[rk[i]] = j;
		}

		memcpy(mn[0], height, sizeof height);
		for(int i = 1; i < 20; i++)
			for(int j = 1; j + (1 << i) - 1 <= N; j++)
				mn[i][j] = min(mn[i - 1][j], mn[i - 1][j + (1 << i - 1)]);
	}
	// int f(int a, int b)
	// {
	// 	int ret = a;
	// 	while(S[a] == S[b] && S[a]) ++a, ++b;
	// 	return a - ret;
	// }
	int query(int a, int b)
	{
		// printf("%d %d\n", a, b);
		// int tmp = f(a, b);
		a = rk[a], b = rk[b];
		// assert(b - a);
		int len = std::__lg(b - a++);
		int ret = min(mn[len][a], mn[len][b - (1 << len) + 1]);
		// assert(tmp == ret);
		// printf("%d\n", ret);
		return ret;
	}
}sa;
int lcp(char *S, char *T) {return S - s <= n && T - t <= m? sa.query(S - s, T - t + n + 1): 0;}
void chmax(int &a, int b) {if(a < b) a = b;}
void solve(char *s, char *t)
{
	memset(g, 0, sizeof g);
	g[0][k] = lcp(s + 1, t + 1);
	for(int i = 0; i < k; i++)
		for(int j = -i; j <= i; j++)
		{
			// printf("%d,%d:%d\n", i, j, g[i][j + k]);
			int len, curs = g[i][j + k] + 1, curt = g[i][j + k] - j + 1;
			// if(i == 0 && j == 0) printf("%d %d\n", curs, curt);

			//1.del
			// if(curs <= n)
			// {
				len = lcp(s + curs + 1, t + curt);
				// if(i==1&&j==1) cout<<len<<endl;
				chmax(g[i + 1][j + 1 + k], g[i][j + k] + len + 1);
			// }
			//2.ins
			// if(t + curt <= ::t + m)
			// {
				len = lcp(s + curs, t + curt + 1);
				chmax(g[i + 1][j - 1 + k], g[i][j + k] + len);
			// }
			//3.rep
			// if(curs <= n && t + curt <= ::t + m)
			// {
				len = lcp(s + curs + 1, t + curt + 1);
				chmax(g[i + 1][j + k], g[i][j + k] + len + 1);
			// }
		}
	// cout<<g[2][2+k]<<endl;
	for(int j = max<int>(n-m+(t-::t),-k); j <= min(k,n-1); j++)
		for(int i = 0; i <= k; i++)
			if(g[i][j + k] >= n && g[i][j + k] - j > 0 && g[i][j + k] - j <= m-(t-::t))
			{
				// if(i==2) cout<<j<<' '<<t-::t+1<<endl;
				++ans[i];
				break;
			}
}
int main()
{
	// freopen(".in", "r", stdin);
	// freopen(".out", "w", stdout);
	scanf("%d%s%s", &k, s + 1, t + 1), n = strlen(s + 1), m = strlen(t + 1);
	sa.init();
	
	// printf("%d\n", lcp(s + 1, t + 1));
	// return 0;

	// solve(s,t+4);
	// return false;
	for(int i = 1; t[i]; i++) solve(s, t + i - 1);
	for(int i = 0; i <= k; i++) printf("%d\n", ans[i]);
	return 0;
}

詳細信息

Test #1:

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

input:

4
aaa
aabbaab

output:

0
5
15
7
1

result:

ok 5 number(s): "0 5 15 7 1"

Test #2:

score: -100
Runtime Error

input:

30
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...

output:


result: