The beautiful values of the palace

Here is a square matrix of n∗nn * nn∗n, each lattice has its value (nnn must be odd), and the center value is n∗nn * nn∗n. Its spiral decline along the center of the square matrix (the way of spiral decline is shown in the following figure:)

The grid in the lower left corner is (1,1) and the grid in the upper right corner is (n , n)

Now I can choose mmm squares to build palaces, The beauty of each palace is equal to the digital sum of the value of the land which it is located. Such as (the land value is 123213123213123213,the beautiful values of the palace located on it is 1+2+3+2+1+3=121+2+3+2+1+3=121+2+3+2+1+3=12) (666666666 -> 181818) (456456456 ->151515)

Next, we ask ppp times to the sum of the beautiful values of the palace in the matrix where the lower left grid(x1,y1x_1,y_1x1​,y1​), the upper right square (x2,y2x_2,y_2x2​,y2​).
Input

The first line has only one number TTT .Representing TTT-group of test data (T≤5)(T\le 5)(T≤5)

The next line is three number: n m pn \ m \ pn m p

The mmm lines follow, each line contains two integers the square of the palace (x,y)(x, y )(x,y)

The ppp lines follow, each line contains four integers : the lower left grid (x1,y1)(x_1,y_1)(x1​,y1​) the upper right square (x2,y2)(x_2,y_2)(x2​,y2​)
Output

Next, p1+p2...+pTp_1+p_2...+p_Tp1​+p2​...+pT​ lines: Represent the answer in turn(n≤106)(m,p≤105)(n \le 10^6)(m , p \le 10^5)(n≤106)(m,p≤105)
样例输入

1
3 4 4
1 1
2 2
3 3
2 3
1 1 1 1
2 2 3 3
1 1 3 3
1 2 2 3

样例输出

5
18
23
17

https://nanti.jisuanke.com/t/41298
在这里插入图片描述
题意: 给一个n*n的蛇形矩阵,给定m个坐标 只有这些点的值是存在的其他都为0 ,每个点的值就是这个点在蛇形矩阵中的编号的每一位数字相加的和 ,q次询问 给x y a b 求x y 和 a b 所围成的矩形中的点的值

方法: 由于这个区间的范围很广 不可能开一个这样的二维数组进行二维前缀和操作
考虑利用树状数组维护一个X 递增的数列
sort 维护一个y递增的数列 不断的往树状数组中加点并且进行类似二维前缀和的操作
对于蛇形矩阵呢?思维题找规律
在这里插入图片描述
Q (a,b) (x,y )所围成的空间的值等于(x,y)+(a-1,b-1)-(a-1,y)-(x,b-1)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6;ll  n;
ll ans[N],f[N];ll tot;
struct node
{
	ll x,y,f,ind,val;
	friend bool operator<(node a,node b)
	//树状数组维护x递增,sort优先判断y 递增不断往里面添加新的点 
	{
		if(a.y==b.y)
		{
			if(a.x==b.x )
			{
				return a.f<b.f;//先添加已经确定的点,再添加要查的点 
			}
			return a.x<b.x;
		}
		return a.y<b.y;
	}
	
}v[N]; 
inline ll lowbit(ll x)
{
	return x&(-x);
}
void add(ll ind,ll val)
{
	while(ind<=n)
	{
		f[ind]+=val;
		ind+=lowbit(ind);
	}
}
ll sum(ll x)
{
	ll tot=0;
	while(x)
	{
		tot+=f[x];
		x-=lowbit(x);
	}
	return tot;
}
ll func(ll x,ll y)
{
	x=x-n/2-1;
	y=y-n/2-1;
	ll t=max(labs(x),labs(y));ll tot=0;
	if(x>=y) tot=n*n-4*t*t-2*t-x-y;
	else tot=n*n-4*t*t+2*t+x+y;
	ll sum=0;
	while(tot)
	{
		sum+=tot%10;
		tot/=10;
	}
	return sum;
}
void solve()
{
	for(int i=0;i<tot;i++)
	{
		if(v[i].f )
		{
			ans[v[i].ind]+=v[i].val *sum(v[i].x );
		}else 
		{
			add(v[i].x,v[i].val );
		}
	}
}
int main()
{
	int tt;scanf("%d",&tt);
	while(tt--)
	{
		int m,q;tot=0;
		scanf("%lld%d%d",&n,&m,&q);
		for(int i=0;i<N;i++)
		{
			f[i]=ans[i]=0;
		}
		for(int i=0;i<m;i++)
		{
			ll a,b;
			scanf("%lld%lld",&a,&b);
			v[tot++]={a,b,0,0,func(a,b)}; 
		}
		for(int i=1;i<=q;i++)
		{
			ll a,b,c,d;
			scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
			a--;b--;//二维前缀和思想
			v[tot++]={c,d,1,i,1};
			v[tot++]={a,b,1,i,1};
			v[tot++]={a,d,1,i,-1};
			v[tot++]={c,b,1,i,-1}; 
			
		}
		sort(v,v+tot);
		solve();
		for(int i=1;i<=q;i++)
		{
			printf("%lld\n",ans[i]);
		}
	}
}

方法参考的是:https://www.cnblogs.com/–HPY-7m/p/11446946.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值