BZOJ 1176 [Balkan 2007] Mokia (cdq divide and conquer solution of three-dimensional partial order)

Keywords: less

BZOJ 1176 [Balkan 2007] Mokia (cdq divide and conquer solution of three-dimensional partial order)

Description

Maintain a W*W matrix with initial values of S. Each operation can increase the weight of a lattice or ask for the total weight of a submatrix. Modify the operand M<=160000, Q<=10000, W<=2000000.

Input

The first row contains two integers, S and W, where S is the initial value of the matrix and W is the size of the matrix.

Next, for each action, one of the three inputs (excluding quotes):

"1 x y a"

"2 x1 y1 x2 y2"

"3"

Enter 1: You need to increase the lattice weight of (x, y) (column y of row x) by a

Input 2: You need to find the weights of all the lattices in the matrix with the lower left corner (x1,y1) and the upper right corner (x2,y2) and output them.

Input 3: Represents the end of the input

Output

For each input 2, output a line, that is, the answer to input 2.

Train of thought:

In fact, this is an on-line matrix plus matrix summation, and cdq divide and conquer can change the on-line problem on two-dimensional plane into three-dimensional off-line problem.

In the previous study of cdq division and conquer, the sum of matrices plus matrices does not understand how to use cdq division and conquer. Recently, seeing this question, I feel that it is a cdq divide-and-conquer board topic. I can also practice how to turn online problems into offline problems. (Looking at the problem, I can't see it. I unconsciously think that this is not a three-dimensional partial order O(____)

How to transform it into a three-dimensional partial order problem? We can add the timestamp of the operation to the third dimension and decompose the query matrix of the second iii operation into the addition and subtraction of four prefix matrices. Then for each modification operation, there is information (x,y,z)(x,y,z)(x,y,z), which represents the coordinates (x,y)(x,y)(x,y) of the modification, and the timestamp is zzz. For each prefix matrix there is information (x,y,z)(x,y,z)(x,y,z), i.e., the upper right coordinate is (x,y)(x,y)(x,y), and the time stamp is Z. For this prefix matrix, the addition and sum at this time is equal to all modification operations (x,y,z) (x,y,z), satisfying X'< x,y'= y,z'= x'\ Le x,y', z'\ Le z'= x,y'= y', z'= y < y,z'= y,z'= y < y,z'. Sum of modified operation values.

Cdq(1,n) resolves the current interval, then these modifications, the point pairs (i,j) asked are classified into three categories, and when they first enter, they are sorted from small to large by xxx.

Attention should be paid to solving the three-dimensional partial order, which must be satisfied after sorting the first dimension. For the point pair less than itself, it must be in the first dimension.

  • i [1,m],j [1,m] i in [1,m],j in [1,m] i [1,m],j [1,m],j [1,m], solved by cdq(l,m)cdq(l,m)cdq(l,m)
  • i [m+1,r],j [l+1,r] i \ in [m+1,r],j in [l+1,r] i [m+1,r],j [l+1,r], and cdq(m+1,r)cdq(m+1,r)cdq(m+1,r) CDQ (m + 1, r) CDQ (m + 1, r)
  • i [l,m],r [m+1,r] i \ in [l,m],r in [m+1,r] i [l,m],r [m+1,r], in the current interval solution, the left and right intervals y from small to large ranking, for the right interval query operation, statistics of the left interval of all modification operations z'= zz' Le zz'= z VV contribution and sum. This part of the operation can be optimized to O(nlogn)O(nlogn)O(nlogn) O(nlogn)O(nlogn)by using double pointer+tree array.

The overall time complexity is O(nlogn2)O(nlogn2)O(nlogn2)O(nlogn2)

Code:

#include <bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int>  P;
const int N=2e5+20;
/*
Three-dimensional partial order, first-dimensional x, second-dimensional y, third-dimensional timestamp d
 There are two kinds of points: one is modification, the other is summation.
*/
struct BITtree
{
    int bt[N];
    int MXN;
    int lowbit(int k)
    {
        return k&-k;
    }
    void add(int k,int v)
    {
        while(k<=MXN)
        {
            bt[k]+=v;
            k+=lowbit(k);
        }
    }
    int getpre(int k)
    {
        int ans=0;
        while(k)
        {
            ans+=bt[k];
            k-=lowbit(k);
        }
        return ans;
    }
    void en(int k)//Values on Destroy k Path
    {
        while(k<=MXN)
        {
            bt[k]=0;
            k+=lowbit(k);
        }
    }
}ooo;
struct pnode
{
    int x,y,z,v;//s is a timestamp, f is flag,v is value
    int k;//Questions indicate that this is the k query, -1 means that this is a modification.
    pnode() {}
    pnode(int x,int y,int z,int v,int k):x(x),y(y),z(z),v(v),k(k) {}
} t[N];
bool cmpx(const pnode & a,const pnode &b)
{
    if(a.x==b.x) return a.z<b.z;
    return a.x<b.x;
}
bool cmpy(const pnode & a,const pnode &b)
{
    return a.y<b.y;
}
int ans[10005];
void cdq(int l,int r)
{
    if(l==r) return ;
    int m=l+r>>1;
    cdq(l,m);
    cdq(m+1,r);
    sort(t+l,t+m+1,cmpy);
    sort(t+m+1,t+r+1,cmpy);
    int p=l-1;
    for(int i=m+1;i<=r;++i)
    {
        while(p<m&&t[p+1].y<=t[i].y) {
            ++p;
            if(t[p].k==-1)
                ooo.add(t[p].z,t[p].v);
        }
        if(t[i].k!=-1)
        {

            int sum=ooo.getpre(t[i].z);
            ans[t[i].k]+=sum*t[i].v;
        }
    }
    for(int i=l;i<=p;++i)
        if(t[i].k==-1) ooo.en(t[i].z);
}
int main()
{
    int n,s,tol=0;
    scanf("%d%d",&s,&n);
    int qid=0,dfn=0;
    while(true)
    {
        int cmd,x,y,xx,yy,a;
        ++dfn;
        scanf("%d",&cmd);
        if(cmd==1)//modify
        {
            scanf("%d%d%d",&x,&y,&a);
            t[++tol]=pnode(x,y,dfn,a,-1);
        }
        else if(cmd==2)
        {
            ++qid;
            scanf("%d%d%d%d",&x,&y,&xx,&yy);
            t[++tol]=pnode(xx,yy,dfn,1,qid);
            t[++tol]=pnode(xx,y-1,dfn,-1,qid);
            t[++tol]=pnode(x-1,yy,dfn,-1,qid);
            t[++tol]=pnode(x-1,y-1,dfn,1,qid);
            ans[qid]=(xx-x+1)*(yy-y+1)*s;
        }
        else
            break;
    }
    ooo.MXN=dfn;
    sort(t+1,t+tol+1,cmpx);
    cdq(1,tol);
    for(int i=1;i<=qid;++i) printf("%d\n",ans[i]);
    return 0;
}

Posted by frigidman on Tue, 24 Sep 2019 21:35:06 -0700