The beautiful values of the palace (thinking + + discrete two-dimensional array of tree maintenance)

Topic links: https://nanti.jisuanke.com/t/41298

Here is a square matrix of n * nnn, each lattice has its value (nn must be odd), and the center value is n * nnn. 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 mm 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 123213123213,the beautiful values of the palace located on it is 1+2+3+2+1+3=121+2+3+2+1+3=12) (666666 -> 1818) (456456 ->1515)

Next, we ask pp times to the sum of the beautiful values of the palace in the matrix where the lower left grid(x_1,y_1x1,y1), the upper right square (x_2,y_2x2,y2).

Input

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

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

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

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

Output

Next, p_1+p_2...+p_Tp1+p2...+pT lines: Represent the answer in turn(n \le 10^6)(m , p \le 10^5)(n106)(m,p105)

Sample input

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

Sample Output

. 5 
18 is 
23 is 
. 17 
ideas: first of all obtains a value corresponding to each position out, O (1) complexity, which is the premise of solving the problem, then the number of points too, there 1e6, so they can not so large arrays, when the game with the map, crazy overtime
reasons guess timeout should be is to use the map, map complexity is log (N), the correct approach is: thinking of scan lines, press x from small to large, when equal x, priority insertion point, instead of inserting a rectangle.
Solution to a problem is to say:

First, n is an odd number, n * n is an odd number, map size is always an odd number, so

X = X - n-/ 2 -. 1
Y = Y - n-/ 2 -. 1;
T = max (ABS (X), ABS (Y)); // At this point determining spiral laps
 if (x> = y ) ans = n * n -4 * t * t -2 * t - x - y; // in the rightward and upward directions

else ans = n * n -4 * t * t + 2 * t + x + y; // in the leftward and downward directions

This way we can weights O (m) is pretreated all the available points.

For each inquiry, it is a rectangular area.

We consider the two-dimensional prefix and its answer is equivalent ans (x2, y2) - ans (x2, y1-1) - ans (x1-1, y2) + ans (x-1, y-1), which ans ( x, y) representative of 1 - x, 1 - y rectangular region and all values.

But obviously two-dimensional space explosion, so we consider how dimensionality reduction.

We can ask a disassembled into four, with a prefix flag is 1 or -1 and are labeled to the query to add or subtract.

Then we can use the method of scanning lines, in accordance with the first sorting x, y and then to map and maintain the value of y after the map with Fenwick tree. Constantly scanning sweep to the right of the vertical line, encountered a point to ask the query again.

But we want to use the scan lines are all points as the modification operation, but can not join the advance Fenwick tree, otherwise it will go wrong answer.

So we all points, and the m th interrogation added 4 * q collection operation, the query flag is -1 or 1, 2 flag is modified, according to x, the first sub-y, again to modify sequentially and in parallel with a y-axis line sweeps from left to right across the abscissa interval, maintaining the current value projected to the y-axis in a tree array. Whenever modification operations, update the value of the tree directly in the array is maintained, encountered query queries directly from the tree array.

Theoretical time complexity is O ((m + 4 * q) log (m + 4 * q));

Look at the code:

/**
x=x-n/2-1
y=y-n/2-1
t=max(abs(x),abs(y));
if(x>=y) ans=n*n-4*t*t-2*t-x-y;
else ans=n*n-4*t*t+2*t+x+y
*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=5e6+5;
typedef long long LL;
int ly[maxn];
int c[maxn];
int Ans[maxn];
int len;
struct Node
{
    int x,y,v,flag,id;
}node[maxn<<2];
bool cmp(const Node a,const Node b)
{
    if(a.x==b.x)
    {
        return a.flag>b.flag;
    }
    return a.x<b.x;
}
LL cal(int x,int y,LL n)
{
    LL ans;
    LL sum=0;
    x=x-n/2-1;
    y=y-n/2-1;
    LL t=max(abs(x),abs(y));
    if(x>=y) ans=n*n-4*t*t-2*t-x-y;
    else ans=n*n-4*t*t+2*t+x+y;
    while(ans)
    {
        sum+=ans%10;
        ans/=10;
    }
    return sum;
}
int getid(int x)
{
    return lower_bound(ly+1,ly+1+len,x)-(ly);
}
int lowbit(int x)
{
    return x&(-x);
}
void add(int x,int v)
{
    while(x<=len)
    {
        c[x]+=v;
        x+=lowbit(x);
    }
}
LL Query(LL x)
{
    LL sum=0;
    while(x)
    {
        sum+=c[x];
        x-=lowbit(x);
    }
    return sum;
}
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        memset(c,0,sizeof(c));memset(Ans,0,sizeof(Ans));
        LL N,M,Q;scanf("%lld%lld%lld",&N,&M,&Q);
        int p=0,p1=0;
        for(int i=1;i<=M;i++)
        {
            int x,y;scanf("%d%d",&x,&y);
            LY [ ++ P1] = Y; // save all Y 
            Node [P ++] .x = X; Node [P] .y = Y; Node [P] .v = CAL (X, Y, N) ; Node [P] .flag = 2 ; // In Flag the representative point is not rectangular 
        }
         for ( int I = . 1 ; I <= Q; I ++ ) 
        { 
            int X1, Y1, X2, Y2; Scanf ( " % D% %% D D D " , & X1, Y1 &, & X2, & Y2); 
            LY [ ++ P1] = Y1- . 1 ; LY [++ P1] = Y2; 
            Node [ ++ P] .x = X1- . 1 ; Node [P] .y = Y1- . 1 ; Node [P] = .flag . 1 ; Node [P] .id = I;   //Representative added to 
            Node [P ++] .x = X1- . 1 ; Node [P] .y = Y2; Node [P] .flag = - . 1 ; Node [P] .id = I; // representatives to Save the 
            node [++ p] .x = X2; Node [P] .y = Y2; Node [P] = .flag . 1 ; Node [P] .id = I;   // representatives to increase the 
            node [++ p ] .x = X2; Node [P] .y = Y1- . 1 ; Node [P] .flag = - . 1 ; Node [P] .id = I; // Representative be subtracted 
        } 
        Sort (Node + . 1 , Node + P + . 1 , CMP); 
        Sort (LY + . 1 , LY + . 1 + P1); 
        len = UNIQUE (LY + . 1 , LY + . 1 + P1) - (LY + . 1 );
         for ( int I = . 1 ; I <= P; I ++) // traverse all the points 
        {
             int X = getId (Node [I] .y);
             IF (Node [I]. == In Flag 2 ) // the representative point is updated directly on the line 
            { 
                the Add (X, Node [I] .v); 
            } 
            the else Ans [Node [I] .id] + = Node [I] .flag * Query (X) ; 
        } 
        for ( int I = . 1 ; I <= Q; I ++ ) 
        { 
            the printf ( " % D \ n- " , Ans [I]); 
        } 
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/caijiaming/p/11518615.html