【NOIP提高组】算循环

Description

【NOIP提高组】算循环_第1张图片

Data Constraint

【NOIP提高组】算循环_第2张图片

Solution

从数据范围很明显可以看出满分做法应该是 O1 的,我们可以慢慢把时间优化起来。首先x、y肯定是不需要枚举的,直接换成计算。然后再假设枚举了上下界,然后推出 ij(nj+1)(mj+1) ,接着再尝试每一行计算 i(ni+1) 。同理最后的这一维可以用类似的方法消掉,消掉后再转化一下形式,变成可以直接利用等差数列和平方和进行计算的式子 (ni=1ni=1i2)(mi=1mi=1i2)

Code

const mo=1000000007;
var
    tmp,sum,ans,n,m,s1,s2,x,y,z,t:int64;
function ksc(x,y:int64):int64;
begin
    t:=trunc(sqrt(x));
    ksc:=((t*t)mod mo*(y mod mo))mod mo;
    ksc:=(ksc+((x-t*t) mod mo)*(y mod mo))mod mo;
    exit(ksc);
end;
procedure deal(re:int64);
begin
    x:=re;y:=re+1;z:=2*re+1;
    if x mod 2=0 then x:=x div 2
       else if y mod 2=0 then y:=y div 2 else z:=z div 2;
    if x mod 3=0 then x:=x div 3
       else if y mod 3=0 then y:=y div 3 else z:=z div 3;
end;
procedure doit(re:int64);
begin
    x:=re;y:=re+1;z:=re+1;
    if x mod 2=0 then x:=x div 2
       else if y mod 2=0 then y:=y div 2 else z:=z div 2;
end;
begin
    readln(n,m);
    deal(n); tmp:=ksc(x,y);tmp:=ksc(tmp,z);
    deal(m); sum:=ksc(x,y);sum:=ksc(sum,z);
    doit(n); s1:=ksc(x,y);s1:=ksc(s1,z);
    doit(m); s2:=ksc(x,y);s2:=ksc(s2,z);
    tmp:=s1-tmp; sum:=s2-sum;
    while tmp<0 do tmp:=tmp+mo;
    while sum<0 do sum:=sum+mo;
    ans:=ksc(tmp,sum);
    writeln(ans);
end.

你可能感兴趣的:(NOIP)