A.The beautiful values of the palace
題解:一個螺旋矩陣,我們要O(1)處理處每個位置數的值,是以必然要找規律,O(1)求每個值。規律就是首先判斷點在哪一層螺旋,然後再根據等差求和,因為每一層的數的個數都是有規律的,然後再判斷在哪一條邊上,然後就能O(1)求。然後我按照x從小到大,按照y從小到大,按照先修改再查詢的順序,但是要注意這裡需要二維求字首和的知識,我們查詢兩個點(x1,y1),(x2,y2)要拆分為四個點(x1-1,y1-1),(x2,y2),(x1-1,y2),(x2,y1-1)然後按照求二維字首和的方法求。我用x來映射y,這就是掃描線。
#include<bits/stdc++.h>
#define ll long long
#define mid (l+r)/2
#define ls o*2
#define rs o*2+1
using namespace std;
const int maxn = 1e6+10;
ll n;
ll ans[maxn],tr[maxn*4];
ll cul(int x,int y)
{
ll ans ;
int tx = x;
tx = min((tx-1)*1LL,n-tx*1LL);
tx = min(tx,y-1);
tx = min(tx*1LL,n-y*1LL);
ans = 4LL*tx*n - 4LL*tx*tx;
if(n-x==tx) ans += n-y+1-tx;
else if(y-tx==1) ans += n-tx*2LL + n-x*1LL - tx*1LL ;
else if(x-tx==1) ans += 2LL*(n-tx*2LL) - 1LL + y*1LL - tx*1LL - 1LL;
else ans += 3LL*(n-tx*2LL) - 2LL + x*1LL - tx*1LL - 1LL;
return ans ;
}
int qu_bit(ll ans)
{
int res = 0;
while(ans)
{
res += ans%10;
ans /= 10LL;
}
return res;
}
struct node{
int x,y;
ll ans;
}p[maxn];
struct point{
int x,y,id,flag;
}tx[maxn];
bool cmp(point a,point b)
{
if(a.x==b.x&&a.y==b.y) return a.flag>b.flag;
else if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
void up(int o,int l,int r,int k,ll v)
{
if(l==r)
{
tr[o] += v;
return ;
}
if(k>mid) up(rs,mid+1,r,k,v);
else up(ls,l,mid,k,v);
tr[o] = tr[ls] + tr[rs];
}
ll qu(int o,int l,int r,int ql,int qr)
{
if(ql>qr) return 0;
if(ql<=l&&qr>=r) return tr[o];
ll ans = 0;
if(ql<=mid) ans += qu(ls,l,mid,ql,qr);
if(qr>mid) ans += qu(rs,mid+1,r,ql,qr);
return ans ;
}
int main()
{
int t;scanf("%d",&t);
while(t--)
{
int m,q,x,y,res;
scanf("%lld%d%d",&n,&m,&q);
int c = 0;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
ll tmp = cul(p[i].x,p[i].y);
p[i].ans = qu_bit(tmp);
++c;
tx[c].x = p[i].x;
tx[c].y = p[i].y;
tx[c].id = q+i;
tx[c].flag = 2;
}
int x1,y1,x2,y2;
for(int i=1;i<=q;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
++c; tx[c].x = x1-1, tx[c].y = y1-1, tx[c].flag = 1,tx[c].id=i;
++c; tx[c].x = x1-1, tx[c].y = y2, tx[c].flag = -1,tx[c].id=i;
++c; tx[c].x = x2, tx[c].y = y1-1, tx[c].flag = -1,tx[c].id=i;
++c; tx[c].x = x2, tx[c].y = y2, tx[c].flag = 1, tx[c].id=i;
}
sort(tx+1,tx+1+c,cmp);
for(int i=1;i<=q;i++) ans[i] = 0;
for(int i=1;i<=c;i++)
{
if(tx[i].flag==2)
{
int now = tx[i].id - q;
up(1,1,n,tx[i].y,p[now].ans);
}
else {
ans[tx[i].id] += tx[i].flag*qu(1,1,n,1,tx[i].y);
}
}
for(int i=1;i<=q;i++)
printf("%lld\n",ans[i]);
for(int i=0;i<maxn*4;i++)
tr[i] = 0;
}
}