您的位置:首页 > 其它

bzoj 1176: [Balkan2007]Mokia

2017-01-04 08:58 309 查看

1176: [Balkan2007]Mokia

Time Limit: 30 Sec  Memory Limit: 162 MB
Submit: 2020  Solved: 901

[Submit][Status][Discuss]

Description

维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000.

Input

第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小

接下来每行为一下三种输入之一(不包含引号):

"1 x y a"

"2 x1 y1 x2 y2"

"3"

输入1:你需要把(x,y)(第x行第y列)的格子权值增加a

输入2:你需要求出以左下角为(x1,y1),右上角为(x2,y2)的矩阵内所有格子的权值和,并输出

输入3:表示输入结束

Output

对于每个输入2,输出一行,即输入2的答案

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

HINT

保证答案不会超过int范围

对于查询操作,我们根据容斥原理将其分解为四个操作,对所有操作按x排序,cdq分治处理时间序,y用树状数组处理。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define N 200010
#define M 2000200
#define lowbit(x) x&(-x)
using namespace std;
inline int read()
{
int x=0,f=1;char ch;
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int w,s,m,q;
struct node{int ip,id,f,x,y,c,t;}p
,tmp
;
bool operator < (node a,node b)
{
if(a.x!=b.x)return a.x<b.x;
if(a.id!=b.id)return a.id<b.id;
if(a.y!=b.y)return a.y<b.y;
return a.f<b.f;
}
int ans
,C[M];
void add(int x,int val)
{
while(x<=w)
{
C[x]+=val;
x+=lowbit(x);
}
}
int ask(int x)
{
int ret=0;
while(x)
{
ret+=C[x];
x-=lowbit(x);
}return ret;
}
void cdq(int l,int r)
{
if(l==r)return;int mid=(l+r)>>1;
for(int i=l;i<=r;i++)
if(p[i].id<=mid&&p[i].f==1)
add(p[i].y,p[i].c);
else if(p[i].id>mid&&p[i].f==2)
ans[p[i].ip]+=p[i].t*ask(p[i].y);
for(int i=l;i<=r;i++)
if(p[i].id<=mid&&p[i].f==1)
add(p[i].y,-p[i].c);
int L=l,R=mid+1;
for(int i=l;i<=r;i++)
if(p[i].id<=mid)
tmp[L++]=p[i];
else tmp[R++]=p[i];
for(int i=l;i<=r;i++)p[i]=tmp[i];
cdq(l,mid);cdq(mid+1,r);
}
int main()
{
s=read(),w=read();
while(1)
{
p[++m].f=read();
if(p[m].f==3){m--;break;}
else if(p[m].f==1)
p[m].x=read(),p[m].y=read(),p[m].c=read(),p[m].id=m;
else
{
int x=read(),y=read(),a=read(),b=read();
p[m].x=x-1,p[m].y=y-1,p[m].t=1,p[m].id=m,p[m].ip=++q;
p[++m].x=a,p[m].y=y-1,p[m].t=-1,p[m].id=m,p[m].ip=q,p[m].f=2;
p[++m].x=x-1,p[m].y=b,p[m].t=-1,p[m].id=m,p[m].ip=q,p[m].f=2;
p[++m].x=a,p[m].y=b,p[m].t=1,p[m].id=m,p[m].ip=q,p[m].f=2;
ans[q]+=(a-x+1)*(b-y+1)*s;
}
}sort(p+1,p+1+m);
cdq(1,m);
for(int i=1;i<=q;i++)
printf("%d\n",ans[i]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: