92分求助
查看原帖
92分求助
901195
__Luna__楼主2024/10/9 18:15

TLE #22 和 #25。
开大随机数范围可以修复掉 TLE,但会爆出大量 WA(包括这两个点)。

#include<bits/stdc++.h>
using namespace std;
long long d[2][262145][4],t[4],k[4];
char s[30000001];
unordered_map<long long,int>m;
mt19937_64 rnd(time(0));
union v
{
	long long a;
	int b[2];
}c;
inline void f(long long*a,long long*b,int p)
{   
    t[0]=((a[0]*b[0])%p+(a[1]*b[2])%p)%p;
    t[1]=((a[0]*b[1])%p+(a[1]*b[3])%p)%p;
    t[2]=((a[2]*b[0])%p+(a[3]*b[2])%p)%p;
    t[3]=((a[2]*b[1])%p+(a[3]*b[3])%p)%p;
    a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=t[3];
}
void g(int o,int n,int p)
{
	if(!(d[o][n][3]||d[o][n][2])&&n!=0)
	{
		g(o,n>>1,p);
		d[o][n][0]=d[o][n>>1][0];
		d[o][n][1]=d[o][n>>1][1];
		d[o][n][2]=d[o][n>>1][2];
		d[o][n][3]=d[o][n>>1][3]; 
		f(d[o][n],d[o][n],p);
		if(n&1)f(d[o][n],d[o][1],p);
	}
}
inline long long*h(long long n,int p)
{
	int a=n&262143,b=n>>18;
	g(0,a,p);
	g(1,b,p);
	k[0]=d[0][a][0];
	k[1]=d[0][a][1];
	k[2]=d[0][a][2];
	k[3]=d[0][a][3]; 
	if(b)f(k,d[1][b],p);
	return k;
}
int main()
{
	int p;
	long long l,n=0;
    cin>>s>>p;
    if(s[1])
	d[0][1][0]=0,d[0][1][1]=d[0][1][2]=d[0][1][3]=1;
	g(0,262144,p);
	d[1][1][0]=d[0][262144][0],d[1][1][1]=d[0][262144][1],d[1][1][2]=d[0][262144][2],d[1][1][3]=d[0][262144][3];
    while(1)
    {
    	int a=rnd()%(2147483645)+1;
    	c.b[0]=h(a,p)[1],c.b[1]=h(a+1,p)[1];
    	if((l=m[c.a])&&l!=a)
    	{
    		l-=a;
    		break;
		}
		m[c.a]=a;
	}
	for(int i=0;s[i];i++)n=(n*10+s[i]-'0')%l;
	cout<<h(n,p)[1]<<endl;
    return 0;
}
2024/10/9 18:15
加载中...