BZOJ1176 Mokia CDQ Division

Keywords: PHP Mobile

Title Description

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

Input Format

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, do each of the three inputs (without quotes):
"1 x y a"
"2 x1 y1 x2 y2"
"3"
Enter 1: You need to increase the grid weight of (x, y) (row x, column y) by a
Input 2: You need to find the weights of all the grids in the matrix with the lower left corner (x1,y1) and the upper right corner (x2,y2) and output
Input 3: Indicates end of input

Output Format

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

Sample

sample input

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

sample output

3
5

Data Range and Tips

Ensure that the answer does not exceed the int range

I worked on a problem called mobile phone before, but later I found that the data of this problem could not be added to a two-dimensional tree array.It's absolutely impossible to say that the mobile phone was IOI2001. There might not have been a tree array or a segment tree at that time. Maybe $n^{2}$was the positive solution.Let's get to the point, how to use the offline division of CDQdalao to solve it.

First we'll do this offline, time-stamp everything, and then we'll have three dimensions.Considering a query that splits into four rectangles plus minus, we can maintain the number of rectangular midpoints enclosed by a coordinate and the origin.And a modification has an impact on the query, if and only if x, y, t are smaller than it, standard 3-D partial order, CDQ set is OK

  

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=200020,M=2000020;
struct node
{
    int a,b,t,f,w;
    int op;
}a[N],t[N];
int b[M],n,ans[N],S,m,tt;
int rd()
{
    int s=0,w=1;
    char cc=getchar();
    while(cc<'0'||cc>'9') {if(cc=='-') w=-1;cc=getchar();}
    while(cc>='0'&&cc<='9') s=(s<<1)+(s<<3)+cc-'0',cc=getchar();
    return s*w;
}
void add(int x,int w)
{
    for(int i=x;i<=m;i+=(i&-i))
        b[i]+=w;
}
int sum(int x)
{
    int ans=0;
    for(int i=x;i;i-=(i&-i))
        ans+=b[i];
    return ans;
}
bool cmp(node a,node b)
{
    if(a.t!=b.t)return a.t<b.t;
    if(a.a!=b.a)return a.a<b.a;
    return a.b<b.b;
}
void CDQ(int l,int r)
{
    if(l==r) return;
    int mid=(l+r)>>1;
    CDQ(l,mid);CDQ(mid+1,r);
    int p=l,q=mid+1,cnt=l-1;
    while(p<=mid&&q<=r)
    {
        //cout<<p<<" "<<q<<endl;
        if(a[p].a<=a[q].a)
        {
            if(a[p].op==0)add(a[p].b,a[p].w);
            t[++cnt]=a[p++];
        }
        else
        {
            if(a[q].op>0)a[q].f+=sum(a[q].b);
            t[++cnt]=a[q++];
        }
    }
    while(p<=mid)
    {
        if(a[p].op==0)add(a[p].b,a[p].w);
        t[++cnt]=a[p++];
    }
    
    while(q<=r)
    {
        if(a[q].op>0) a[q].f+=sum(a[q].b);
        t[++cnt]=a[q++];
    }
    for(int i=l;i<=mid;i++) if(a[i].op==0)add(a[i].b,-a[i].w);
    for(int i=l;i<=r;i++) a[i]=t[i];
}
bool cmp2(node a,node b)
{
    if(a.t==b.t) return a.op<b.op;
    return a.t<b.t;
}
void asd(int x,int y,int t,int op,int w)
{
    //cout<<tt<<" "<<x<<" "<<y<<endl;
    a[++tt].a=x,a[tt].b=y;a[tt].t=t;
    a[tt].op=op;a[tt].w=w;
}
int main()
{
    S=rd(),m=rd()+1;
    int cnt=0,xa,xb,ya,yb,x,w,y;
    for(int i=1;;i++)
    {
        int op=rd();
        if(op==3) break;
        if(op==2)
        {
            cnt++;
            xa=rd()+1,ya=rd()+1;
            xb=rd()+1,yb=rd()+1;
            asd(xb,yb,i,1,0);
            asd(xa-1,yb,i,2,0);
            asd(xb,ya-1,i,3,0);
            asd(xa-1,ya-1,i,4,0);
        }
        if(op==1)
        {
            x=rd()+1,y=rd()+1,w=rd();
            asd(x,y,i,0,w);
        }
    }//(xa,yb)-(xa,ya-1)-(xb-1,yb)+(xb-1,ya-1)
    sort(a+1,a+tt+1,cmp);
    CDQ(1,tt);
    for(int i=1;i<=tt;i++)
    {
        //cout<<i<<" "<<a[i].t<<endl;
        switch(a[i].op)
        {
            case 1:
            {
                ans[a[i].t]+=a[i].f+(a[i].a*a[i].b*S);
                break;
            }
            case 2:
            {
                ans[a[i].t]-=a[i].f+(a[i].a*a[i].b*S);
                break;
            }
            case 3:
            {
                ans[a[i].t]-=a[i].f+(a[i].a*a[i].b*S);
                break;
            }
            case 4:
            {
                ans[a[i].t]+=a[i].f+(a[i].a*a[i].b*S);
                break;
            }
        }
        
    }
    sort(a+1,a+tt+1,cmp2);
    for(int i=1;i<=tt;i++)
    {
        if(a[i].op==4) printf("%d\n",ans[a[i].t]);
    }
}
/*
g++ 1.cpp -o 1
./1
0 4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
*/
/*
g++ -g 1.cpp -o 1
gdb -q 1
b 42
r
0 4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
*/

Posted by Dawg on Fri, 26 Jul 2019 16:43:10 -0700