纯hash求助二分
查看原帖
纯hash求助二分
142549
hbhz_zcy楼主2022/3/12 14:42

猜测hash应该是没问题,可能二分挂掉了,但是看不出来,也没有小数据调试。
50pts,WA 2,6,7,8,10

#include<iostream>
#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn=600,mod0=4;const LL mod1=998244353,mod2=1e9+7;
int N,M;LL ls[maxn],ha[maxn][maxn][2],hb[maxn][maxn][2],mi[maxn];
struct node{LL v;int id;}f[maxn<<1];
bool cmp(const node &x,const node &y){
	if(x.v==y.v)  return x.id<y.id;
	return x.v<y.v;
}
bool calc(int l,int r){
//	printf("s %d %d\n",l,r);
	for(int i=1;i<=N;i++)  f[i]=(node){((ha[i][r][0]-ha[i][l-1][0])<<31)^(ha[i][r][1]-ha[i][l-1][1]),0};
//	for(int i=1;i<=N;i++)  printf("%lld ",f[i].v);
//	putchar('\n');
	for(int i=1;i<=N;i++)  f[i+N]=(node){((hb[i][r][0]-hb[i][l-1][0])<<31)^(hb[i][r][1]-hb[i][l-1][1]),1};
//	for(int i=1;i<=N;i++)  printf("%lld ",f[i+N].v);
//	putchar('\n');putchar('\n');
	sort(f+1,f+2*N+1,cmp);
	for(int i=1;i<N*2;i++)
		if(f[i].v==f[i+1].v&&f[i].id!=f[i+1].id)  return 0;
	return 1;//0:bad
}
int main(){
	scanf("%d%d",&N,&M);
	mi[0]=1;
	for(int i=1;i<=M;i++)  mi[i]=mi[i-1]*mod0%mod2;
//	putchar('\n');
	for(int i=1;i<=N;i++){
		int lstop=0;
		char c=getchar();
		while(c<'A'||c>'Z')  c=getchar();
		while('A'<=c&&c<='Z'){
			if(c=='A')  ls[++lstop]=0;
			else if(c=='C')  ls[++lstop]=1;
			else if(c=='T')  ls[++lstop]=2;
			else if(c=='G')  ls[++lstop]=3;
			c=getchar();
		}
		for(int j=1;j<=M;j++)
			ha[i][j][0]=(ha[i][j-1][0]+ls[j]*mi[j])%mod1,
			ha[i][j][1]=(ha[i][j-1][1]+ls[j]*mi[j])%mod2;
//		for(int j=1;j<=M;j++)  printf("%lld ",ha[i][j]);
//		putchar('\n');
	}
	for(int i=1;i<=N;i++){
		int lstop=0;
		char c=getchar();
		while(c<'A'||c>'Z')  c=getchar();
		while('A'<=c&&c<='Z'){
			if(c=='A')  ls[++lstop]=0;
			else if(c=='C')  ls[++lstop]=1;
			else if(c=='T')  ls[++lstop]=2;
			else if(c=='G')  ls[++lstop]=3;
			c=getchar();
		}
		for(int j=1;j<=M;j++)
			hb[i][j][0]=(hb[i][j-1][0]+ls[j]*mi[j])%mod1,
			hb[i][j][1]=(hb[i][j-1][1]+ls[j]*mi[j])%mod2;
//		for(int j=1;j<=M;j++)  printf("%lld ",hb[i][j]);
//		putchar('\n');
	}
	for(int l=1,r=M;;){
		if(l==r){printf("%d\n",l);return 0;}
		int m=(l+r)/2,flag=0;
		for(int i=1;i+m-1<=M;i++)
			if(calc(i,i+m-1)){flag=1;break;}
		if(flag)  r=m;
		else l=m+1;
//		printf("flag=%d\n",flag);
	}
	return 0;
}
2022/3/12 14:42
加载中...