很裸的一道CDQ分治吧
拆操作 询问区间的时候 拆成询问四个子区间然后加加减减
根据时间顺序来二分 然后用插排降一维 最后一维树状数组维护前缀和
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
struct O
{
int x,y,ans,No,op;
int add;
inline friend bool operator <(O a,O b)
{return a.No<b.No||a.No==b.No&&a.op<b.op;}
inline void print()
{
printf(" x:%d y:%d ans:%d No:%d op:%d add:%d",x,y,ans,No,op,add);
puts("");
}
}Line[1000001];
int BIT[5000001];
int base;
inline int low_bit(int a){return a&-a;}
inline void Add(int x,int delta)
{for(int i=x;i<=base;i+=low_bit(i))BIT[i]+=delta;}
inline int Query(int x)
{int res=0;for(int i=x;i;i^=low_bit(i))res+=BIT[i];return res;}
void Solve(int L,int R)
{
if(L^R)
{
int Mid=(L+R)>>1;
Solve(L,Mid),Solve(Mid+1,R);
int j=L;
for(int i=Mid+1;i<=R;i++)
if(Line[i].add==0)
{
while(j<=Mid&&Line[j].x<=Line[i].x)
{
if(Line[j].add)Add(Line[j].y,Line[j].add);
j++;
}
Line[i].ans+=Query(Line[i].y);
}
j--;
while(j>=L)
{
if(Line[j].add)Add(Line[j].y,-Line[j].add);
j--;
}
O A[R-L+2];
int x=L,y=Mid+1,con=0;
while(x<=Mid&&y<=R)
if(Line[x].x<=Line[y].x)A[++con]=Line[x],x++;
else A[++con]=Line[y],y++;
while(x<=Mid)
A[++con]=Line[x],x++;
while(y<=R)
A[++con]=Line[y],y++;
/* for(int i=1;i<=con;i++)
A[i].print();
*/ for(int i=L;i<=R;i++)
Line[i]=A[i-L+1];
// puts("");puts("");puts("");puts("");
}
else
return;
}
int main()
{
int S,W;
read(S),read(W);
base=W<<1;
/*for(int i=1;i<=W;i++)
Add(i,S);
*/
int n=0,j,jk=0;
while(true)
{
read(j);
if(j==3)break;
n++;
if(j==1)
{
read(Line[n].x);
read(Line[n].y);
read(Line[n].add);
Line[n].No=0; }
else
{
++jk;
int x1,x2,y1,y2;
read(x1),read(y1),read(x2),read(y2);
Line[n]=(O){x1-1,y1-1,0,jk,1,0};
Line[n].ans+=S*(x2-x1+1)*(y2-y1+1);
Line[++n]=(O){x2,y2,0,jk,2,0};
Line[++n]=(O){x1-1,y2,0,jk,3,0};
Line[++n]=(O){x2,y1-1,0,jk,4,0};
}
}
Solve(1,n);
sort(Line+1,Line+1+n);
int i=1;
while(Line[i].No==0)i++;
for(;i<=n;i+=4)
printf("%d\n",Line[i].ans+Line[i+1].ans-Line[i+2].ans-Line[i+3].ans);
return 0;
}