Topic links: [ https://www.luogu.com.cn/problem/P4390 ]
Express Edition meaning of the questions:
Maintains a \ (W * W \) matrix, the initial values are \ (S \) . Each operation can increase the weight of a lattice, or ask for a total weighted value of the sub-matrix. Operands Modify \ (M < = 160 000 \) , the number of query \ (Q <= 10000, W <= 2000000. \)
Ideas:
The first reaction is a two-dimensional array of tree, however, see the \ (W <= 2000000 \) will be prohibitive.
Think today in practice \ (cdq \) partition, so go in this direction by.
First of all, easy to think of the total weight of the sub-matrix can be separated into four sub-prefix matrix and weights.
So, value and weight matrix and the right to seek prefix child how it?
The initial value \ (S \) added directly on it.
Considering the operation of a modification to the summing contribute, if and only if it is inside the prefix sub-matrix of the request.
Prefix sub-matrix provided to the bottom right coordinates \ ((X, Y) \) , then for contributing to its point P, satisfies \ (xp <= x \) and \ (yp <= y \)
found that the original is a bare three dimensional partial ordering, the partition can cdq.
Precautions:
- There can be zero, sentenced to special queries about when Fenwick tree.
- To open an array bigger, because a long inquiry will be split four.
There are variable names do not disabled wrong hands.
code:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+50;
const int W=2e6+50;
int s,w,n;
struct node{int x,y,v,tp,id,ans;}a[N],b[N];
bool operator<(node x,node y){return x.x<y.x;}
inline int read()
{
int s=0,w=1; char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')w=-1;
for(;isdigit(ch);ch=getchar())s=(s<<1)+(s<<3)+(ch^48);
return s*w;
}
struct tree{
int c[W];
inline int lowbit(int x){return x&(-x);}
inline void add(int x,int v)
{
if(!x) return;
for(;x<=w;x+=lowbit(x))c[x]+=v;
}
inline int query(int x)
{
if(!x) return 0;
int ans=0;
for(;x;x-=lowbit(x))ans+=c[x];
return ans;
}
}T;
void cdq(int l,int r)
{
if(l==r) return;
int mid=l+r>>1;
cdq(l,mid);cdq(mid+1,r);
sort(b+l,b+mid+1);sort(b+mid+1,b+r+1);
int i=l,j=mid+1;
for(;j<=r;++j)
{
for(;i<=mid&&b[i].x<=b[j].x;++i)
if(b[i].tp==1) T.add(b[i].y,b[i].v);
if(b[j].tp==2)
a[b[j].id].ans+=T.query(b[j].y);
}
for(int e=l;e<i;++e)
if(b[e].tp==1) T.add(b[e].y,-b[e].v);
}
int main()
{
s=read(),w=read();
while(7)
{
int opt=read();
if(opt==3) break;
if(opt==1)
a[++n].x=read(),a[n].y=read(),a[n].v=read(),a[n].tp=1,a[n].id=n;
else
{
int x11=read(),y11=read(),x22=read(),y22=read();
a[++n].x=x22,a[n].y=y22,a[n].tp=2,a[n].id=n;
a[++n].x=x11-1,a[n].y=y22,a[n].tp=2,a[n].id=n;
a[++n].x=x22,a[n].y=y11-1,a[n].tp=2,a[n].id=n;
a[++n].x=x11-1,a[n].y=y11-1,a[n].tp=2,a[n].id=n;
}
}
for(int i=1;i<=n;++i) b[i]=a[i];
cdq(1,n);
for(int i=1;i<=n;++i)
if(a[i].tp==2)
{
int bas=abs(a[i+1].x-a[i+2].x)*abs(a[i+1].y-a[i+2].y)*s;
printf("%d\n",bas+a[i].ans-a[i+1].ans-a[i+2].ans+a[i+3].ans);
++i,++i,++i;
}
return 0;
}