DTOJ#5182. T3 是我的你不要抢

ω \omega ω 有很多字符串,它们都由小写字母构成。

给你 n n n 个字符串 a i a_i ai ,和 Q Q Q 个询问,每次对两个串 S = a i , T = a j S = a_i, T = a_j S=ai,T=aj 询问最大的 L ( 0 ≤ L ≤ min ⁡ { ∣ S ∣ , ∣ T ∣ } ) L(0 \leq L \leq \min\{|S|,|T|\}) L(0Lmin{ S,T}) 使得 S [ ∣ S ∣ − L + 1 … ∣ S ∣ ] = T [ 1 … L ] S[|S| - L + 1 \dots |S|] = T[1\dots L] S[SL+1S]=T[1L]

第一行两个正整数 n , Q , n, Q, n,Q, 表示一共有 n n n 个字符串,以及有 Q Q Q 个询问。

下面 n n n 行,每行一个字符串 a i a_i ai

下面 Q Q Q 行,每行两个正整数 x , y , x, y, x,y, 表示询问 S = a x S = a_x S=ax T = a y T = a_y T=ay

输出 Q Q Q 行,每行一个非负整数,表示最大的 L L L

样例输入

3 6
wwq
eew
qwe
1 2
2 3
1 3
2 1
3 2
3 1

样例输出

0
0
1
1
1
0

对于所有数据,保证 ∣ a i ∣ ≥ 1 , ∑ i = 1 n ∣ a i ∣ ≤ 6 × 1 0 5 , 1 ≤ 1 0 6 |a_i| \geq 1, \sum_{i = 1} ^ {n} |a_i| \leq 6 \times 10^5, 1 \leq 10^6 ai1,i=1nai6×105,1106

对于第 1 ∼ 2 1 \sim 2 12 组数据,保证 n = 1 n = 1 n=1

对于第 3 ∼ 6 3 \sim 6 36 组数据,保证 n ≤ 10 n \leq 10 n10

对于第 7 ∼ 10 7 \sim 10 710 组数据,保证 ∑ i = 1 n ∣ a i ∣ ≤ 5 × 1 0 3 \sum_{i = 1} ^ { n} |a_i| \leq 5 \times 10^3 i=1nai5×103

对于第 11 ∼ 14 11 \sim 14 1114 组数据,保证只出现 a b ab ab 两种字符,且 ∑ i = 1 n ∣ a i ∣ ≤ 5 × 1 0 4 \sum_{i = 1} ^ { n} |a_i| \leq 5 \times 10^4 i=1nai5×104

对于第 15 ∼ 20 15 \sim 20 1520 组数据,没有特殊限制。

镇海中学 csp2020 模拟2

题解:
暴力过了。。
考虑暴力 H a s h Hash Hash 匹配,同时记忆化, O ( n n ) O(n\sqrt n) O(nn )

#include<bits/stdc++.h>
#define N 1000005
typedef unsigned long long ll;
using namespace std;
inline int read(){
    
    
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){
    
    if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){
    
    x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const ll P1=133331,P2=998244353;
const int T=6000;
ll p1[N],p2[N];
vector<ll> a1[N],a2[N];
int len[N];
char s[N];
int to[N],q[N],pre[T+5][T+5],b[T+5][T+5];
struct node{
    
    
	int len,id;
}pai[N];
int pt;
bool cmp(node a,node b){
    
    return a.len>b.len;}
int main(){
    
    
//freopen("string.in","r",stdin);
//	freopen("string.out","w",stdout);
	//printf("%d\n",sizeof(pre)>>20);
	int n=read(),Q=read();
	p1[0]=p2[0]=1;
	for(int i=1;i<N;++i)p1[i]=p1[i-1]*P1,p2[i]=p2[i-1]*P2;
	//int ke=1;
	int las=0;
	for(int i=1;i<=n;++i){
    
    
		scanf("%s",1+s);
		a1[i].push_back(0);
		a2[i].push_back(0);
		len[i]=strlen(1+s);
		pai[++pt].len=len[i],pai[pt].id=i;
		for(int j=1;j<=len[i];++j){
    
    
			ll now=s[j]-'a';
			a1[i].push_back(a1[i][j-1]*P1+now);
			a2[i].push_back(a2[i][j-1]*P2+now);
			//ll now=(a[i][j-1]*P+s[j]-'a');
			//cout<<s[j]<<endl;
			//h1[i][a1[i][j]]=1;
			//h2[i][a2[i][j]]=1;
		}
	}
    sort(pai+1,pai+1+n,cmp);
    for(int i=1;i<=min(T,n);++i){
    
    
    	q[++q[0]]=pai[i].id;
    	to[pai[i].id]=q[0];
    }
    while(Q--){
    
    
    	int x=read(),y=read();
    	if(to[x]&&to[y]&&b[to[x]][to[y]]){
    
    
    		printf("%d\n",pre[to[x]][to[y]]);
    		continue;
    	}
    	int r=min(len[x],len[y]),ans=0;
    	for(int i=r;i;--i){
    
    
    		ll now1=a1[x][len[x]]-a1[x][len[x]-i]*p1[i],now2=a2[x][len[x]]-a2[x][len[x]-i]*p2[i];
    		ll to1=a1[y][i],to2=a2[y][i];
    		if(now1==to1&&now2==to2){
    
    
    			ans=i;break;
    		}
    	}
    	//cout<<len[x]<<" "<<len[y]<<endl;
    	//cout<<x<<" "<<y<<endl;
    	//cout<<a1[y][2]<<" "<<a1[x][len[x]]-a1[x][len[x]-2]*P1*P1<<endl;
    	if(to[x]&&to[y]){
    
    
    		b[to[x]][to[y]]=1;
            pre[to[x]][to[y]]=ans;
        }
        printf("%d\n",ans);
    }
    return 0;
}
/*
2 1
ababab
bbbbbb
1 2

*/

猜你喜欢

转载自blog.csdn.net/CSDNzhanghongyu/article/details/110094601
T3
今日推荐