Description
构造一类矩形:
先构造矩形 M 1 = [ 1 ] M_1=\begin{bmatrix}1\end{bmatrix} M1=[1]。
对于 i ≥ 1 i\geq1 i≥1, T i + 1 T_{i+1} Ti+1 从 T i T_i Ti 构造而来,方法为在最右侧和最下侧插入新的一行一列,自右上到左下 2 i + 1 2i+1 2i+1 个数分别填入 i 2 + 1 , i 2 + 2 … ( i + 1 ) 2 i^2+1,i^2+2\dots(i+1)^2 i2+1,i2+2…(i+1)2。
比如:
- M 2 = [ 1 2 4 3 ] M_2=\begin{bmatrix}1&2\\4&3\end{bmatrix} M2=[1423]
- M 3 = [ 1 2 5 4 3 6 9 8 7 ] M_3=\begin{bmatrix}1&2&5\\4&3&6\\9&8&7\end{bmatrix} M3= 149238567
- M 4 = [ 1 2 5 10 4 3 6 11 9 8 7 12 16 15 14 13 ] M_4=\begin{bmatrix}1&2&5&10\\4&3&6&11\\9&8&7&12\\16&15&14&13\end{bmatrix} M4= 14916238155671410111213
令左上角坐标为 ( 1 , 1 ) (1,1) (1,1),从上至下第 i i i 行,从左至右第 j j j 个数的坐标为 i , j i,j i,j。
共 T T T 组询问,每次询问 x 1 , y 1 , x 2 , y 2 x_1,y_1,x_2,y_2 x1,y1,x2,y2,求 ∑ x 1 ≤ i ≤ x 2 , y 1 ≤ j ≤ y 2 M ∞ [ i ] [ j ] \sum_{x_1\le i\le x_2,y_1\le j\le y_2}M_\infty [i][j] ∑x1≤i≤x2,y1≤j≤y2M∞[i][j]。
如果答案在十位数以上,只输出答案的最后十位,前面的数位用 ...
代替。
否则输出完整的答案。
前置芝士
两个公式,可以了解一下相关证明:
1 2 + 2 2 + ⋯ + n 2 = n × ( n + 1 ) × ( 2 × n + 1 ) 6 1^2+2^2+\dots+n^2=\dfrac{n\times(n+1)\times(2\times n+1)}{6} 12+22+⋯+n2=6n×(n+1)×(2×n+1)
1 + 2 + ⋯ + n = ( n + 1 ) × n 2 1+2+\dots+n=\dfrac{(n+1)\times n}{2} 1+2+⋯+n=2(n+1)×n
Solution
对于求一个矩形内所有数值的和,通常运用容斥来转换。
在此题上,设 S x , y S_{x,y} Sx,y 为 ∑ 1 ≤ i ≤ x , 1 ≤ j ≤ y M ∞ [ i ] [ j ] \sum_{1\le i\le x,1\le j\le y}M_\infty [i][j] ∑1≤i≤x,1≤j≤yM∞[i][j]。
利用容斥: a n s = S x 2 , y 2 − S x 1 − 1 , y 2 − S x 2 , y 1 − 1 + S x 1 − 1 , y 1 − 1 ans=S_{x_2,y_2}-S_{x_1-1,y_2}-S_{x_2,y_1-1}+S_{x_1-1,y_1-1} ans=Sx2,y2−Sx1−1,y2−Sx2,y1−1+Sx1−1,y1−1。
所以只要会求 S x , y S_{x,y} Sx,y 就好了。
钦定 y ≤ x y\le x y≤x。
对于一个左上角的矩形,其一定包含一个边长为 y y y 的正方形。
而正方形的和就是 1 + 2 + ⋯ + y 2 1+2+\dots+y^2 1+2+⋯+y2,利用等差数列求和公式得出。
剩下的一部分分类讨论。
第一种情况,红色部分为 ( ( y + 1 ) 2 + ( y + 2 ) 2 + ⋯ + x 2 ) × y − ( 1 + 2 + ⋯ + y − 1 ) ((y+1)^2+(y+2)^2+\dots+x^2)\times y-(1+2+\dots+y-1) ((y+1)2+(y+2)2+⋯+x2)×y−(1+2+⋯+y−1)。
第二种情况,红色部分为 ( ( y 2 + ( y + 1 ) 2 + ⋯ + ( x − 1 ) 2 ) + ( x − y ) ) × y + ( 1 + 2 + ⋯ + y − 1 ) ((y^2+(y+1)^2+\dots+(x-1)^2)+(x-y))\times y+(1+2+\dots+y-1) ((y2+(y+1)2+⋯+(x−1)2)+(x−y))×y+(1+2+⋯+y−1)。
很明显,对于 S a , b S_{a,b} Sa,b,当 a > b a>b a>b 时为第一种情况,当 a ≤ b a\le b a≤b 时为第二种情况。
Code
#include<bits/stdc++.h>
using namespace std;
int t;
#define _int __int128 //不能取模,所以开__int128
_int read(){
_int x=0,f=1;
char ch=getchar();
while(ch<'0'&&ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
return x*f;
}
_int calc(_int x){
if(x==0) return 0;
return x*(x+1)*(2*x+1)/6; //平方和公式
}
_int get(_int x,_int y){
_int ans=0;
if(x>y){
ans+=(y*y+1)*y*y/2; //正方形
_int cnt=calc(x)-calc(y);
ans+=cnt*y;
ans=ans-(x-y)*y*(y-1)/2;
}else{
ans+=(x*x+1)*x*x/2; //正方形
_int cnt=calc(y-1)-calc(x-1)+y-x;
ans+=cnt*x;
ans=ans+(y-x)*x*(x-1)/2;
}
return ans;
}
void print(_int x,int cnt){
if(cnt==11) return;
print(x/10,++cnt);
putchar(x%10+'0');
}
void print2(_int x,bool f){
if(x){
print2(x/10,0);
putchar(x%10+'0');
}else if(f){
putchar('0');
}
}
void solve(){
_int a=read(),b=read(),c=read(),d=read();
_int ans=((get(c,d)-get(a-1,d))-get(c,b-1))+get(a-1,b-1); //容斥
if(ans>=10000000000){
printf("...");
print(ans,1);
}else print2(ans,1);
printf("\n");
}
int main(){
t=read();
while(t--){
solve();
}
return 0;
}