zjnu2017校赛M会长的正方形

4 篇文章 0 订阅
2 篇文章 0 订阅

出现正方形顶点都在格点上的情况:

设x,y。比如x=0,y=1表示的就是边长为1的正方形,x=0,y=2表示边长为2的正方形,x=1,y=2表示边长为根号5的正方形,x=1,y=3表示的是边长为根号9的正方形。那么特定的x,y可以表示一种正方形。

经过观察,x+y是刚好放下这个正方形所要的格子的边长。x*x+y*y是这个正方形的面积。

再观察,假设格子大小为n,m(n<m),设一种正方形边长为L;

L=1时,这种正方形的个数=n*m;

L=2,个数=(n-1)*(m-1);

L=3,个数=(n-2)*(m-2);

L=n,个数=1*(m-n+1);

就可以直接求x+y=L的正方形的个数。

在x+y=L的各种正方形中,满足条件的正方形类型有x1=0,y1=L; x2=1,y2=L-1……x'=L-1,y'=1;每一种都是(n-L+1)*(m-L+1)个。

这些正方形面积加起来是:( 0*0+L*L )+( 1*1+(L-1)*(L-1) )+......+( (L-1)*(L-1)+1*1 );

再观察一下,发现是两个平方前缀和想加。。。不写了,看代码就会知道的。

#include<cstdio>
#include<cstring>
typedef long long ll;
const int mod=1e9+7;
int t;
ll n,m;
ll sum[10005];
ll num(int i){
    return (n-i+1)*(m-i+1)%mod;
}
ll area(int i){
    return (sum[i-1]+sum[i])%mod;
}
int main()
{
    sum[1]=1;
    for(int i=2;i<=10001;i++){
        sum[i]=(sum[i-1]+i*i%mod)%mod;
    }
    scanf("%d",&t);
    while(t--){
        scanf("%lld%lld",&n,&m);
        int limit=n;
        if(m<n) limit=m;

        ll ans1=0,ans2=0;
        for(int i=1;i<=limit;i++){
            ans1=(ans1+num(i)*i%mod)%mod;
            ans2=(ans2+num(i)*area(i)%mod)%mod;
        }
        printf("%lld %lld\n",ans1,ans2);
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值