【大意】
有一个无穷的矩阵,大概是这样:
1 2 5 10 17 26 …
4 3 6 11 18 27 …
9 8 7 12 19 28 …
16 15 14 13 20 29 …
25 24 23 22 21 30 …
36 35 34 33 32 31 …
… … … … … … …
T 个询问,每次框一个矩形要你求和。如果和太大超过10 个字符,前面用… 表示,后面只保留10 位。
【解答】
i
,
若
x≥y
y(4x+3x2+2x3−y−3xy+y3)6
否则
(−x+x3+4y+3xy−3y2+2y3)x6
具体的推法就是算一个矩形的和时,用一个正方形加上一个长方形来算。
例如 Fm,n=Fn,n+∑m−ni=1[(n+i)2+(n+i)2−1+...(n+i)2−(n−1)]
展开来就行了
#include <bits/stdc++.h>
#define LL long long
#define LD long double
using namespace std;
const LL mod=(LL)1e+11;
const LL rev3=66666666667LL;
LL T(LL a,LL b){return ((a*b-(LL)((LD)a*b/mod)*mod+mod)%mod);}
LL C(LL x,LL y) {
if(x>=y)
return T(T(T(4,x)+T(3,T(x,x))+T(2,T(x,T(x,x)))-y-T(3,T(x,y))+T(y,T(y,y))+mod+mod,y),rev3*5);
else
return T(T(T(x,T(x,x))-x+T(4,y)+T(3,T(x,y))-T(3,T(y,y))+T(2,T(y,T(y,y)))+mod+mod,x),rev3*5);
}
LD W(LD x,LD y) {
if(x>=y)
return (4*x+3*x*x+2*x*x*x-y-3*x*y+y*y*y)*y/6;
else
return (x*x*x-x+4*y+3*x*y-3*y*y+2*y*y*y)*x/6;
}
int main() {
int T,a,b,c,d;
for(scanf("%d",&T);T--;) {
scanf("%d%d%d%d",&a,&b,&c,&d);
LL t=(C(c,d)-C(c,b-1)-C(a-1,d)+C(a-1,b-1)+mod+mod)%mod;
if(W(c,d)-W(c,b-1)-W(a-1,d)+W(a-1,b-1)<1e+10)
printf("%I64d\n",t/10);
else
printf("...%010I64d\n",t/10);
}
}