HDU5970

分析

这题除了公式难推一点外没有什么难点了,重要的还是看公式。
首先根据gcd的求法可以知道,F[i][j]=[i+kj][j]
然后接下来的所有式子几乎都利用这个展开。

#include<cstdio>
const int lqs=700;
int f[lqs][lqs],c[lqs][lqs];
int gcd(int x,int y,int &c){
	c=0;
	while(y){
		c++;
		int t=x%y;
		x=y;
		y=t;
	}
	return c*x*x;
}
int main(){
	int T;
	scanf("%d",&T);
	for(int i=1;i<=666;i++)
		for(int j=1;j<=666;j++)
			f[i][j]=gcd(i,j,c[i][j]);
	while(T--){
		int n,m,p;
		scanf("%d%d%d",&n,&m,&p);
		#define ll long long
		ll ans=0;
		for(int j=1;j<=m;j++)
			for(int i=1;i<=j&&i<=n;i++)
				for(int k=0;k<c[i][j]&&i+k*j<=n;k++){
					ll t1=(i+j*k)*1ll*j/f[i][j];
					ll t2=c[i][j]*j*j*1ll/f[i][j];
					ll t3=(n-(i+j*k))/(c[i][j]*j)+1;
					ans=(ans+t1*t3%p+(t3-1)*t3/2%p*t2%p)%p;
				}
		printf("%lld\n",ans);
	}
}
posted @ 2020-05-30 07:14  An_Fly  阅读(133)  评论(0编辑  收藏  举报