链接
http://www.lydsy.com/JudgeOnline/problem.php?id=1176
题解
1A系列。
我好像连续好几道题都没1A了,我这样怎么参加省选啊。我好弱啊。
这个东西是可以
CDQ
分治的,把操作顺序看做第一维,
x
、
细节不多说,就是
CDQ
分治套路。
代码
//CDQ分治+BIT
#include <cstdio>
#include <algorithm>
#define maxn 500000
#define lowbit(x) (x&-x)
using namespace std;
int N, M, bit[2000010], tot, S, W;
struct opt{int type, x, y, a, id, ans;}o[maxn];
inline int read(int x=0)
{
char c=getchar(); bool f=0;
while(c<48 or c>57)f=f or c=='-',c=getchar();
while(c>=48 and c<=57)x=(x<<1)+(x<<3)+c-48, c=getchar();
return f?-x:x;
}
inline bool operator<(opt a, opt b){return a.x<b.x;}
void add(int pos, int v){if(!pos)return;for(;pos<=W;pos+=lowbit(pos))bit[pos]+=v;}
int sum(int pos)
{if(!pos)return 0;int ans=0;for(;pos;pos-=lowbit(pos))ans+=bit[pos];return ans;}
void cdq(int l, int r)
{
int mid=(l+r)>>1, i, j;
if(l==r)return;
cdq(l,mid), cdq(mid+1,r);
sort(o+l,o+mid+1), sort(o+mid+1,o+r+1);
for(i=l,j=mid+1;j<=r;j++)
{
for(;o[i].x<=o[j].x and i<=mid;i++)if(o[i].type==1)add(o[i].y,o[i].a);
o[j].ans+=sum(o[j].y);
}
for(j=l;j<i;j++)add(o[j].y,-o[j].a);
}
void init()
{
int type, x1, y1, x2, y2;
S=read(), W=read();
for(tot=1;;tot++)
{
if((type=read())==3)break;
x1=read(), y1=read();
if(type==1)
{
o[tot].type=1;
o[tot].x=x1, o[tot].y=y1;
o[tot].a=read();
}
else if(type==2)
{
x2=read(), y2=read();
x1--, y1--;
o[tot].type=o[tot+1].type=o[tot+2].type=o[tot+3].type=2;
o[tot].x=x1, o[tot].y=y1;
o[tot+1].x=x2, o[tot+1].y=y2;
o[tot+2].x=x1, o[tot+2].y=y2;
o[tot+3].x=x2, o[tot+3].y=y1;
tot+=3;
}
else break;
}
tot--;
for(int i=1;i<=tot;i++)o[i].id=i;
}
inline bool cmp(opt a, opt b){return a.id<b.id;}
void show()
{
int i, ans;
sort(o+1,o+tot+1,cmp);
for(i=1;i<=tot;i++)
{
if(o[i].type==1)continue;
ans=(o[i+1].y-o[i].y)*(o[i+1].x-o[i].x)*S;
ans+=o[i].ans+o[i+1].ans-o[i+2].ans-o[i+3].ans;
printf("%d\n",ans);
i+=3;
}
}
int main()
{
init();
cdq(1,tot);
show();
return 0;
}