QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#730439#5312. Levenshtein DistanceerduolongWA 1030ms16792kbC++142.5kb2024-11-09 20:15:142024-11-09 20:15:18

Judging History

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

  • [2024-11-09 20:15:18]
  • 评测
  • 测评结果:WA
  • 用时:1030ms
  • 内存:16792kb
  • [2024-11-09 20:15:14]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+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(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];
		memcpy(y,x,sizeof x);
		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);//modify
				if(i+x+j<=m) f[t+1][_j+1]=max(f[t+1][_j+1],x);//delete
				if(x+1<=n) f[t+1][_j-1]=max(f[t+1][_j-1],x+1);//add
			}
		}
		int L=max(i,i-1+n-k),R=min(m,i-1+n+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;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 9948kb

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: 1030ms
memory: 16432kb

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: 724ms
memory: 16792kb

input:

30
BBAAABAABBBA
ABBABBBBAABAAAABABBBAABAABBAABAAAAAABAABABBAAAABAAAAABABAABAABBABBAAAABBBBAABBABAAABAABAABBBBBABBABABBBBABBBBAAABBABABBBBAAABBBBAAAABABABABABABABAAABBBBBAABAABAABBAABBBAABBBBBBBABAABAABAABABAABAAABAABBBAABABBABBAAABAAAABABABBABBBAAABBBAAAABBBBABABABAABAABBBBBBBBBAABBBABABBBABAABBABBA...

output:

17
662
8225
50285
166630
310061
345412
280345
227173
209157
203003
198554
105280
102155
99780
97740
96068
94741
93644
92732
92070
91535
91152
90836
90588
90420
90289
90201
90121
90069
90036

result:

wrong answer 3rd numbers differ - expected: '8230', found: '8225'