关于开大数组
查看原帖
关于开大数组
326780
Albert_van楼主2021/11/9 18:43

RT,代码中 am 数组(在 5353 行)是我用来跑 CRT 的,由于这题同余方程只有四个,所以它们的下标开到 44 理论上就够了

但是我开到 5525pts,大红大紫

我试着把这两个数组开大一点,开到 1000100035pts

开到 5000500070pts

开到 100001000090pts

开到 1500015000AC

Why???

(P.S. 这两个数组下面紧接着是 CRT 函数,在 main 函数里面预处理出了这两个数组之后调用了 CRT

#include <cstdio>
#include <cmath>
#define int long long

using namespace std;

struct pair{
	int x,y;
};

pair exgcd(int a,int b){
	if(!b) return (pair){1,0};
	pair k=exgcd(b,a%b);
	return (pair){k.y,k.x-a/b*k.y};
}

int inv(int x,int k){
	return (exgcd(x,k).x%k+k)%k;
}

int d_[]={0,2,3,4679,35617};

int n,d[5000000],cnt;

void fuck_divisor(){
	int sqr = sqrt(n);
	for(int i=1;i<=sqr;++i) if(n%i==0){
		d[++cnt]=i;
		if(n/i!=i) d[++cnt]=n/i;
	}
}

int ftr[5000000],k;

int c(int a,int b){
	return ftr[a]*inv(ftr[a-b],k)%k*inv(ftr[b],k)%k;
}

int C(int a,int b){
	return b?c(a%k,b%k)*C(a/k,b/k)%k:1;
}

int fuck(){
	ftr[0]=1;
	for(int i=1;i<=k;++i) ftr[i]=ftr[i-1]*i%k;
	int res=0;
	for(int i=1;i<=cnt;++i) res=(res+C(n,d[i]))%k;
	return res;
}

const int M=999911658;

int a[15000],m[15000];

int CRT(){
	int res=0;
	for(int i=1;i<=4;++i) res+=a[i]*(M/m[i])*inv(M/m[i],m[i]);
	return (res%M+M)%M;
}

int ksm(int x,int p){
	int res=1;
	while(p){
		if(p&1) res=res*x%(M+1);
		x=x*x%(M+1);p>>=1;
	}
	return res;
}

signed main()
{
	int g;scanf("%lld%lld",&n,&g);
	if(g%(M+1)==0) return !putchar('0');
	fuck_divisor();
	for(int i=1;i<=4;++i) k=m[i]=d_[i],a[i]=fuck();
	printf("%lld",ksm(g,CRT()));
}
2021/11/9 18:43
加载中...