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