这题被我HASH过去了,建议加强数据
查看原帖
这题被我HASH过去了,建议加强数据
101407
Binah楼主2022/11/30 13:47

代码如下:

使用hash维护数列里连续1/2/3位出现的字符串数量,维护同色颜色段的(长度*颜色)的出现次数,最后对满足的进行特判,然后过了

/*********************************************************************
    程序名:
    版权:
    作者:
    日期: 2022-11-30 12:37
    说明:
*********************************************************************/
#include <bits/stdc++.h>
using namespace std;
#define N 2000005
int n;
char a[N],b[N];
int mp[531441];
long long ans1,ans2;

inline int str(char *q,int pos,int l,int cnt)
{
	int ret=0;
	while(cnt--)
	{
		ret*=27;
		ret+=q[pos];
		pos++;
		if(pos>l)
			pos-=l;
	}
	if(ret>531441)
	{
		assert(0);
	}
	return ret;
}

int str3(char *q,int l,int pos,int cnt)
{
	int ret=0;
	while(cnt--)
	{
		ret*=27;
		ret+=q[pos];
		pos+=3;
		while(pos>l)
			pos-=l;
	}
	return ret;
}
stack<int>ans;
#define mod 998244353


bool chk(int l)
{
	int atot=0;
	int btot=0;
	long long aaa=1;
	for(int i=1; i<=l; i++)
	{
		atot=(27ll*atot+a[i])%mod;;
		btot=(27ll*btot+b[i])%mod;;
		aaa=27ll*aaa%mod;
	}
	aaa-=1;
	//printf("%d\n",aaa);
	aaa=mod-aaa;
	for(int i=1; i<=l; i++)
	{
		//printf("%d %d\n",atot,btot);;
		if(atot==btot)
			return 1;
		btot=(27ll*btot+aaa*b[i])%mod;
	}
	return 0;
}

void insert(int &a1,int &b1,bool &c1,int &t1,char *a,int i)
{
	if(b1==i-1)
	{
		if(a[i]==a[i-1])
		{
			b1++;
			a1=mp[a[1]*b1%10000];
		}
		else
			t1=1,c1=0,a1+=mp[a[i]];
	}
	else
	{
		if(a[i]==a[i-1])
		{
			a1-=mp[a[i-1]*t1%10000];
			t1++;
			a1+=mp[a[i-1]*t1%10000];
		}
		else if(a[i]==a[1])
		{
			a1-=mp[a[1]*b1%10000];
			t1=b1+1;
			a1+=mp[a[1]*t1%10000];
			c1=1;
		}
		else if(c1)
		{
			a1-=mp[a[1]*t1%10000];
			a1+=mp[a[1]*(t1-b1)%10000];
			a1+=mp[a[1]*b1%10000];
			a1+=mp[a[i]];
			c1=0;
			t1=1;
		}
		else
		{
			a1+=mp[a[i]];
			t1=1;
		}
	}
}
int a1,a2;
int b1,b2;
int t1,t2;
bool c1,c2;

int main()
{
	scanf("%d\n",&n);
	scanf("%s",a+1);
	scanf("%s",b+1);
	srand(time(0));
	for(int i=0; i<531441; i++)
	{
		mp[i]=rand()%998244353;
	}
	for(int i=1; i<=n; i++)
	{
		a[i]-='a';
		a[i]++;
		b[i]-='a';
		b[i]++;
	}
	ans.push(1);
	ans.push(2);
	ans.push(3);
	for(int i=1; i<=3; i++)
	{
		ans1+=mp[a[i]];
		ans1+=mp[str(a,i,3,2)];
		ans1+=mp[str(a,i,3,3)];

		ans2+=mp[b[i]];
		ans2+=mp[str(b,i,3,2)];
		ans2+=mp[str(b,i,3,3)];
	}
	a1=mp[a[1]];
	a2=mp[b[1]];
	t1=1;
	b1=1;
	b2=1;
	t2=1;
	c1=1;
	c2=1;
	for(int i=2; i<=3; i++)
	{
		insert(a1,b1,c1,t1,a,i);
		insert(a2,b2,c2,t2,b,i);
	}
//	printf("init\n");

	for(int i=4; i<=n; i++)
	{
		insert(a1,b1,c1,t1,a,i);
		insert(a2,b2,c2,t2,b,i);

		ans1+=mp[a[i]];
		ans1-=mp[str(a,i-1,i-1,2)];
		ans1+=mp[str(a,i-1,i,2)];
		ans1+=mp[str(a,i,i,2)];
		ans1-=mp[str(a,i-2,i-1,3)];
		ans1-=mp[str(a,i-1,i-1,3)];
		ans1+=mp[str(a,i,i,3)];
		ans1+=mp[str(a,i-2,i,3)];
		ans1+=mp[str(a,i-1,i,3)];
		ans1%=998244353;

		ans2+=mp[b[i]];
		ans2-=mp[str(b,i-1,i-1,2)];
		ans2+=mp[str(b,i-1,i,2)];
		ans2+=mp[str(b,i,i,2)];
		ans2-=mp[str(b,i-2,i-1,3)];
		ans2-=mp[str(b,i-1,i-1,3)];
		ans2+=mp[str(b,i,i,3)];
		ans2+=mp[str(b,i-2,i,3)];
		ans2+=mp[str(b,i-1,i,3)];
		ans2%=998244353;

		if(ans1==ans2 && a1==a2)
		{
			ans.push(i);
		}

	}

	while(!ans.empty())
	{
		//	printf("check %d\n",ans.top());
		if(chk(ans.top()))
		{
			printf("%d",ans.top());
			return 0;
		}
		ans.pop();
	}
	printf("WTF\n");
	return 0;
}
2022/11/30 13:47
加载中...