快速荷叶叶变换 【NOIP2016提高A组模拟9.4】

来源:互联网 发布:木马盗号软件 编辑:程序博客网 时间:2024/05/16 21:19

题目

这里写图片描述
样例输入:
一行,包含两个整数N,M。
3 4

样例输出:
1个整数,FHT(N,M) mod 1000000007的值。
1

数据范围:
对于 40% 的数据,1 ≤ N,M ≤ 1000
对于 60% 的数据,1 ≤ N,M ≤ 10^6
对于 100% 的数据,1 ≤ N,M ≤ 10^9


剖解题目

。。。。。。


思路

仔细考虑求这个模数和之间的关系。


解法

40%:暴力即可。
60%:公式可化为

i=1N(N)mod(i)j=1M(M)mod(j)

公式里空格打不了,只好用个括号来区分QwQ。
100%:
其实发现,这n个数中,分为几段,每一段给予的贡献是有规律的。
对于n/2+1~n-1的数,每一个数都是对于答案的贡献是公差为1的等差数列;同理对于n/3+1~n/2的数,他的贡献是公差为2的等差数列,计算即可。
时间O(N)


代码

#include<cstdio>#include<algorithm>#include<cstring>#define ll long long#define fo(i,a,b) for(int i=a;i<=b;i++)using namespace std;const ll mo=1e9+7;ll ans,k,n,m;ll doing(ll n){    ll r=n,l,k=1,d,sum=0,h;    while (k){        ++k;        l=n/k; d=l+1; h=n%r;        if (d==r) break;        ll t=h+(r-d)*(k-1);        sum=(sum+(t+h)*(r-l)/2)%mo;        r=l;    }    fo(i,2,r) sum=(sum+n%i)%mo;    return sum;}int main(){//  freopen("T.in","r",stdin);     scanf("%lld%lld",&n,&m);    ll ans1=doing(n),ans2=doing(m);    ll ans=ans1*ans2%mo;    printf("%lld",ans);}

这里写图片描述

0 0
原创粉丝点击