您的位置:首页 > 其它

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

2016-10-21 19:48 393 查看

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

(File IO): input:loop.in output:loop.out

Time Limits: 1000 ms Memory Limits: 524288 KB

Description



Input



Output



Sample Input

167 198


Sample Output

906462341


Data Constraint



解题思路(我的)

首先我们可以将题目所求写成这样的形式:

∑i=1n∑j=1m∑k=1n∑l=1m∑x=ik∑y=jl1

20分:call题目上的标O(n^6)

40分:

首先我们可以知道:

∑i=x1y1∑j=x2y2f(i)∗g(j)=(∑i=x1y1f(i))∗(∑j=x2y2g(j))(这很显然啊)

于是公式化为

∑i=1n∑j=1m∑k=1n−i+1∑l=1m−j+1∑x=1k∑y=1l1

—–>

∑i=1n∑j=1m∑k=1n−i+1∑l=1m−j+1kl

O(n^4)枚举

60分:

你要会逆元

很明显公式又可以化为

∑i=1n∑j=1m(∑k=1n−i+1k)∗(∑l=1m−j+1l)

—–>

∑i=1n∑j=1m(n−i+2)∗(n−i+1)2∗(m−j+2)∗(m−j+1)2

—–>

∑i=1n∑j=1m(n−i+2)∗(n−i+1)∗(m−j+2)∗(m−j+1)4

—–>

∑ni=1∑mj=1(n−i+2)∗(n−i+1)∗(m−j+2)∗(m−j+1)4

—–>

∑ni=1∑mj=1(n2−2ni+3n+i2−3i+2)∗(m2−2mj+3m+j2−3j+2)4

O(n^2)解决

80分:

再将公示转化得到

(∑ni=1(n2−2ni+3n+i2−3i+2))∗(∑mj=1(m2−2mj+3m+j2−3j+2))4

O(n)解决

100分:

有八十分的思路还想不到100的?除非你不会用公式……



∑i=1ni=(1+i)∗i/2

∑i=1ni2=n∗(n+1)∗(2n+1)/6

原式化为

(n3−n2(n+1)+3n2+(2n+1)(n+1)n6−32(n+1)n+2n)∗(m3−m2(m+1)+3m2+(2m+1)(m+1)m6−32(m+1)m+2m)4

—–>

(n3−n3−n2+3n2+13n3+12n2+16n−frac32n2−frac32n+2n)∗(m3−m3−m2+3m2+13m3+12m2+16m−frac32m2−frac32m+2m)4

—–>

(13n3+n2+23n)∗(13m3+m2+23m)4

—–>

(n3+3n2+2n)∗(m3+3m2+2m)36

O(1)解决

codes:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const long long maxn=1e9+7;
long long n,m;

long long get(long long x,long long y)
{
long long ans=1;
while(y)
{
if(y&1)
{
ans=(ans*x)%maxn;
}
x=(x*x)%maxn;
y>>=1;
}
return ans;
}

long long Get(long long x)
{
return((x*x)%maxn*x%maxn+3*x*x%maxn+2*x%maxn)%maxn;
}

int main()
{
freopen("loop.in","r",stdin);
freopen("loop.out","w",stdout);
scanf("%lld%lld",&n,&m);
long long x=Get(n%maxn),y=Get(m%maxn);
printf("%lld",(x*y%maxn)*get(36,maxn-2)%maxn);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: