类欧几里得算法的一种几何解释

本文内容来自我的 OI 笔记,由于技术原因只能导出为图片格式。

代码实现

题目链接

LL pws(int n,int k){
	if(!k) return (LL)n%MOD;
	if(k==1) return (LL)n*(LL)(n+1)/2ll%MOD;
	if(k==2) return (LL)n*(LL)(n+1)%MOD*(LL)(2*n+1)%MOD*inv6%MOD;
}
void calc(int a,int b,int c,int n,LL &f,LL &g,LL &h){// a,c,n>=0
	if(!a){
		int nn=max(0,b/c);
		f=(LL)nn*(LL)n%MOD;
		g=(LL)nn*pws(n,1)%MOD;
		h=pws(nn,1)*(LL)n%MOD;
	}
	else if(b<0){
		int mv=(-b+a-1)/a,nb=b+mv*a;
		if(n<=mv)
			f=g=h=0ll;
		else{
			calc(a,nb,c,n-mv,f,g,h);
			(g+=f*mv)%=MOD;
		}
		if(n>=mv){
			(f+=(LL)(nb/c))%=MOD;
			(g+=(LL)mv*(LL)(nb/c))%=MOD;
			(h+=pws(nb/c,1))%=MOD;
		}
	}
	else if(a>=c){
		LL da=a/c;
		LL df=da*pws(n,1);
		LL dg=da*pws(n,2);
		LL dh=da*inv2%MOD*pws(n,1)-da*da%MOD*inv2%MOD*pws(n,2);// +da*g reserved
		calc(a-c*da,b,c,n,f,g,h);
		(f+=df)%=MOD;
		(g+=dg)%=MOD;
		(h+=dh+g*da)%=MOD;
	}
	else{
		int nn=((LL)a*(LL)n+(LL)b)/(LL)c;
		calc(c,-b-1,a,nn,f,g,h);
		f=((LL)n*(LL)nn-f)%MOD;
		LL ng=(pws(n,1)*(LL)nn-h)%MOD,nh=(pws(nn,1)*(LL)n-g)%MOD;
		g=ng;h=nh;
	}
}
void answer(int a,int b,int c,int n,LL &f,LL &g,LL &h){
	++n;
	b-=a;
	calc(a,b,c,n,f,g,h);
	f=(f+MOD*MOD)%MOD;g=(g+MOD*MOD)%MOD;h=(h+MOD*MOD)%MOD;
	h=(h*2ll+MOD-f)%MOD;
	g=(g+MOD-f)%MOD;
}
posted @ 2021-04-21 11:38  TianyiQ  阅读(135)  评论(0编辑  收藏  举报