QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#730549#5312. Levenshtein DistanceerduolongWA 1002ms30848kbC++142.5kb2024-11-09 20:39:072024-11-09 20:39:08

Judging History

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

  • [2024-11-09 20:39:08]
  • 评测
  • 测评结果:WA
  • 用时:1002ms
  • 内存:30848kb
  • [2024-11-09 20:39:07]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
const int N=8e5+10,M=65,V=30,K=18;
int f[M][M];
int k;
char str[N];
int sa[N],x[N],y[N],c[N],rk[N],height[N];
int st[N][K];
int ans[N];
int g[N];
int n,m;

int Lcp(int i,int j)
{
//	printf("Lcp: %d %d ",i,j);
	if(i>n || j>m) return 0;
	j+=n+1;
	int l=rk[i],r=rk[j];
	if(l>r) swap(l,r);
	l++;
	int c=log2(r-l+1);
	int res=min(st[l][c],st[r-(1<<c)+1][c]);
//	printf("%d\n",res)?;
	return res;
}

void SA(int n)
{
	int m=128;
	for(int i=1;i<=n;i++) c[x[i]=str[i]]++;
	for(int i=1;i<=m;i++) c[i]+=c[i-1];
	for(int i=n;i>=1;i--) sa[c[x[i]]--]=i;
	
	for(int k=1;k<=n;k<<=1)
	{
		int num=0;
		for(int i=n-k+1;i<=n;i++) y[++num]=i;
		for(int i=1;i<=n;i++) if(sa[i]>k) y[++num]=sa[i]-k;
		
		for(int i=1;i<=m;i++) c[i]=0;
		for(int i=1;i<=n;i++) c[x[i]]++;
		for(int i=2;i<=m;i++) c[i]+=c[i-1];
		for(int i=n;i>=1;i--) sa[c[x[y[i]]]--]=y[i],y[i]=0;
		swap(x,y);
		x[sa[1]]=1,num=1;
		for(int i=2;i<=n;i++)
		{
			x[sa[i]]=(y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])?num:++num;
		}
		
		if(num==n) break;
		m=num;
	}
	
	for(int i=1;i<=n;i++) rk[sa[i]]=i;
	
	for(int i=1,k=0;i<=n;i++)
	{
		if(rk[i]==1) continue;
		if(k) k--;
		int j=sa[rk[i]-1];
		while(i+k<=n && j+k<=n && str[i+k]==str[j+k]) k++;
		height[rk[i]]=k;
	}
	
	for(int i=2;i<=n;i++) st[i][0]=height[i];
	for(int j=1;j<K;j++)
	{
		for(int i=1;i+(1<<j)-1<=n;i++)
		{
			st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
		}
	}
}

signed main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	
	cin>>k;
	
	cin>>(str+1);
	n=strlen(str+1);
	str[n+1]='0';
	cin>>(str+n+2);
	m=strlen(str+n+2);
	
	SA(n+m+1);
	
//	cout<<n<<" "<<m<<"\n";
	
	for(int i=1;i<=m;i++)
	{
		memset(f,-0x3f,sizeof f);
		f[0][k]=0;
		for(int t=0;t<=k;t++)
		{
			for(int j=-k,_j=0;j<=k;j++,_j++)
			{
				if(f[t][_j]<0) continue;
				int &x=f[t][_j];
				x+=Lcp(x+1,i+x+j);
				if(x+1<=n && i+x+j<=m) f[t+1][_j]=max(f[t+1][_j],x+1);//m
				if(i+x+j<=m) f[t+1][_j+1]=max(f[t+1][_j+1],x);//d
				if(x+1<=n) f[t+1][_j-1]=max(f[t+1][_j-1],x+1);//a
			}
		}
		int L=max(i,i-1+n-2*k),R=min(m,i-1+n+2*k);
		for(int x=L;x<=R;x++) g[x]=k+1;
		for(int j=-k,_j=0;j<=k;j++,_j++)
		{
			int &v=g[i-1+n+j];
			v=0;
			while(v<=k && f[v][_j]<n) v++;
		}
		
		for(int x=L;x<R;x++) g[x+1]=min(g[x+1],g[x]+1);
		for(int x=R;x>L;x--) g[x-1]=min(g[x-1],g[x]+1);
		for(int x=L;x<=R;x++) ans[g[x]]++;
	}
	
	for(int i=0;i<=k;i++) cout<<ans[i]<<"\n";
	
	return 0;
}

详细

Test #1:

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

input:

4
aaa
aabbaab

output:

0
5
15
7
1

result:

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

Test #2:

score: 0
Accepted
time: 1002ms
memory: 28576kb

input:

30
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...

output:

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

result:

ok 31 numbers

Test #3:

score: -100
Wrong Answer
time: 298ms
memory: 30848kb

input:

30
BBAAABAABBBA
ABBABBBBAABAAAABABBBAABAABBAABAAAAAABAABABBAAAABAAAAABABAABAABBABBAAAABBBBAABBABAAABAABAABBBBBABBABABBBBABBBBAAABBABABBBBAAABBBBAAAABABABABABABABAAABBBBBAABAABAABBAABBBAABBBBBBBABAABAABAABABAABAAABAABBBAABABBABBAAABAAAABABABBABBBAAABBBAAAABBBBABABABAABAABBBBBBBBBAABBBABABBBABAABBABBA...

output:

0
0
0
3
40
86
100
76
82
85
65
65
1079595
89989
89987
89986
89985
89984
89983
89982
89981
89980
89979
89978
89977
89976
89975
89974
89973
89972
89971

result:

wrong answer 1st numbers differ - expected: '17', found: '0'