CF249E Endless Matrix 题解

Description

构造一类矩形:

先构造矩形 M 1 = [ 1 ] M_1=\begin{bmatrix}1\end{bmatrix} M1=[1]

对于 i ≥ 1 i\geq1 i1 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] x1ix2,y1jy2M[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] 1ix,1jyM[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,y2Sx11,y2Sx2,y11+Sx11,y11

所以只要会求 S x , y S_{x,y} Sx,y 就好了。

钦定 y ≤ x y\le x yx

对于一个左上角的矩形,其一定包含一个边长为 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++y1)

第二种情况,红色部分为 ( ( 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++(x1)2)+(xy))×y+(1+2++y1)

很明显,对于 S a , b S_{a,b} Sa,b,当 a > b a>b a>b 时为第一种情况,当 a ≤ b a\le b ab 时为第二种情况。

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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值