【JZOJ4819】算循环
Description
给出一个 n×m 的矩阵,矩阵中每个格子的面积为1,求所有子矩阵的面积和。
Data Constraint
Solution
对于80分,我们可以发现一个公式:
ans=∑ni=1i(i+1)2⋅∑mi=1i(i+1)2
那么,我们现在要求 1×2+2×3+⋯+n(n+1) 。
显然
i(i+1)=i2+i
,那么上式就变成了:
∑i=1ni2+∑i=1ni=n(n+1)(2n+1)6+n(n+1)2
。
然后就是 O(1) 算法了。
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define mo 1000000007
#define ll long long
using namespace std;
ll pow(ll m,int n)
{
ll b=1;
while(n)
{
if(n%2) b=b*m%mo;
n/=2;
m=m*m%mo;
}
return b;
}
int main()
{
freopen("loop.in","r",stdin);
freopen("loop.out","w",stdout);
ll n,m;
cin>>n>>m;
n%=mo;
m%=mo;
ll t1=(n*(n+1)%mo*(2*n+1)%mo*pow(6,mo-2)+n*(n+1)%mo*pow(2,mo-2))%mo;
ll t2=(m*(m+1)%mo*(2*m+1)%mo*pow(6,mo-2)+m*(m+1)%mo*pow(2,mo-2))%mo;
ll ans=t1*t2%mo*pow(4,mo-2)%mo;
cout<<ans;
}