UOJ Logo

NOI.AC

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#210933#2068. 最长公共前缀mygr00ms0kbC++3.0kb2024-08-08 11:42:392024-08-08 12:39:55

answer

#include<bits/stdc++.h>
using namespace std;
const int Max=2e3+5,nmax=2e7+5;

class SA{
public:
	string s;
	int sa[nmax],x[nmax],y[nmax],c[nmax];
	int n,m=505,num;
	void init()
	{
		for(int i=1;i<=n;i++)x[i]=s[i-1],c[x[i]]++;
		for(int i=1;i<=m;i++)c[i]=c[i-1]+c[i];
		for(int i=n;i>=1;i--)sa[c[x[i]]--]=i;
		
		for(int k=1;k<=n;k*=2)
		{
			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=1;i<=m;i++)c[i]=c[i]+c[i-1];
			for(int i=n;i>=1;i--)sa[c[x[y[i]]]--]=y[i],y[i]=0;
			num=1;swap(x,y);
			x[sa[1]]=1;
			for(int i=2;i<=n;i++)
			{
				if(y[sa[i]+k]==y[sa[i-1]+k])
					x[sa[i]]=num;
				else
					x[sa[i]]=++num;
			}
			m=num;
			if(m==n)
				return ;
		}
	}
	int rk[nmax],h[nmax];
	void geth()
	{
		for(int i=1;i<=n;i++)
			rk[sa[i]]=i;
		int k=1;
		for(int i=1;i<=n;i++)
		{
			if(k)k--;
			int j=sa[rk[i]-1];
			while(s[i+k-1]==s[j+k-1])
				k++;
			h[rk[i]]=k;
		}
	}
	
}S;
class Seg_tree{
public:
	struct node{
		int Min;
	}p[nmax*4];
	void pushup(int now)
	{
		p[now].Min=min(p[now<<1].Min,p[now<<1|1].Min);
	}
	void build(int now,int l,int r)
	{
		if(l==r)
		{
			p[now].Min=S.h[l];
			return ;
		}
		int mid=(l+r)>>1;
		build(now<<1,l,mid);
		build(now<<1|1,mid+1,r);
		pushup(now);
	}
	int query(int now,int l,int r,int nl,int nr)
	{
		if(l<=nl and nr<=r)
			return p[now].Min;
		int mid=(nl+nr)>>1,ans=0x7fffffff;
		if(l<=mid)
			ans=min(ans,query(now<<1,l,r,nl,mid));
		if(mid<r)
			ans=min(ans,query(now<<1|1,l,r,mid+1,nr));
		return ans;
	}
}T;
int n,m,q;
char Map[Max][Max];
int ps[Max][Max][4];
char getc()
{
	char c=getchar();
	while(c<'a' or 'z'<c)
		c=getchar();
	return c;
}
int getC()
{
	char c=getchar();
	while(c<'A' or 'Z'<c)
		c=getchar();
	if(c=='H')
		return 0;
	if(c=='V')
		return 1;
	return 2;
}
int main()
{
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			Map[i][j]=getc();
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			S.s+=Map[i][j];
			ps[i][j][0]=++S.n;
		}
		S.s+=124;
		++S.n;
	}
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)
		{
			S.s+=Map[j][i];
			ps[j][i][1]=++S.n;
		}
		S.s+=124;
		++S.n;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m and i+j-1<=n;j++)
		{
			S.s+=Map[i+j-1][j];
			ps[i+j-1][j][2]=++S.n;
		}
		S.s+=124;
		++S.n;
	}
	for(int i=2;i<=m;i++)
	{
		for(int j=1;j<=n and i+j-1<=m;j++)
		{
			S.s+=Map[j][i+j-1];
			ps[j][i+j-1][2]=++S.n;
		}
		S.s+=124;
		++S.n;
	}
	S.init();
	S.geth();
	T.build(1,1,S.n);
	while(q--)
	{
		int X[2],Y[2],P[2],ty[2];
		cin>>X[0]>>Y[0];ty[0]=getC();
		cin>>X[1]>>Y[1];ty[1]=getC();
		P[0]=S.rk[ps[X[0]][Y[0]][ty[0]]];
		P[1]=S.rk[ps[X[1]][Y[1]][ty[1]]];
		if(P[0]>P[1])swap(P[0],P[1]);
		if(P[0]==P[1])
		{
			printf("%d\n",min(n-X[0]+1,m-Y[0]+1));
			continue;
		}
		else
		{
			printf("%d\n",T.query(1,P[0]+1,P[1],1,S.n));
		}
	}
}

详细

小提示:点击横条可展开更详细的信息

Subtask #1:

score: 0
Time Limit Exceeded

Test #1:

score: 0
Time Limit Exceeded

input:

1000 2000 10000
awanannwnnaaawwnwawanwnwaaaanwnaaananwawwwwnannannawwwawwaaaaannwnwnwnnaaawaawawannn...

output:


result:


Subtask #2:

score: 0
Time Limit Exceeded

Test #3:

score: 0
Time Limit Exceeded

input:

2000 2000 1000000
gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg...

output:


result:


Subtask #3:

score: 0
Skipped

Subtask #4:

score: 0
Skipped