【NOIP2016提高A组模拟10.15】算循环

Description

这里写图片描述
意思就是让你运行这个程序输出结果

Input

n和m( n,m<=1018

Output

答案,tmp

Sample Input

167 198

Sample Output

906462341

Solution

首先对题目中的程序搞一搞
改变顺序:有关n的放一起,有关m的放一起
拆开:分别算出有关n的答案和有关m的答案,然后乘起来
继续拆开,套用公式搞定

i=1ni2=n(n+1)(2n+1)6

为了应对Cold_Chair对我的步步紧逼,这里写一个公式的简单证明过程:
假设公式成立,那么对于第n项的公式就是 n(n+1)(2n+1)6
然后加 (n+1)2
然后展开,加进去,再化简,就变成了 (n+1)(n+2)(2(n+1)+1)6
又变回了原公式

Code

#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
#define fo(i,a,b) for(ll i=a;i<=b;i++)
#define mo 1000000007ll
#define ny2 500000004
#define ny6 166666668
using namespace std;
ll hh(ll n)
{
    ll an=0;
    an=(n*n)%mo;an=(an*n)%mo;
    an=(an-((((((2*n)*(n-2))%mo)*ny2)%mo)*n)%mo+mo)%mo;
    an=(an+(((n-1)*(n-2))%mo)*ny2)%mo;
    n=(n-2);
    an=(an+(((((n*(n+1))%mo)*(2*n+1))%mo)*ny6))%mo;
    an=(an*ny2)%mo;
    return an%mo;
}
int main()
{
    freopen("loop.in","r",stdin);freopen("loop.out","w",stdout);
    ll n,m,an=0;
    scanf("%lld%lld",&n,&m);
    an=(hh(n%mo)*hh(m%mo))%mo;
    printf("%lld",an);
    fclose(stdin);fclose(stdout);
}
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值