您的位置:首页 > 其它

bzoj4066 简单题

2016-12-10 22:33 295 查看
【题意】

n*n网格,初始每个点权值为0,m个操作,共2种:

1.(x,y)点权+z

2.查询矩形(x1,y1)(x2,y2)的点权和

强制在线

【数据范围】

n<=500000,m<=200000

【思路】

kd-tree模板题,注意kd-tree需定期重构。

矩形求和的计算方法:

若某点子树边框包含于查询矩形,则直接更新答案。

若某点子树边框与查询矩形不相交,则忽略该子树。

【时间复杂度】

O(m*sqrt(m))

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200010
using namespace std;

struct aa{int d[2], x;}a
;
struct tt{int l, r, mx[2], mn[2], d[2], x, sum;}t
;
int n, m, l, temp, lastans, D, B, x1, x2, y1, y2;

inline int read(){
int x=0, f=1; char ch=getchar();
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;
}

bool operator<(aa a, aa b){return a.d[D]<b.d[D];}

void update(int i){
t[i].sum=t[t[i].l].sum+t[t[i].r].sum+t[i].x;
for(int j=0; j<=1; j++){
t[i].mx[j]=t[i].mn[j]=t[i].d[j];
if(t[i].l){
t[i].mx[j]=max(t[i].mx[j], t[t[i].l].mx[j]);
t[i].mn[j]=min(t[i].mn[j], t[t[i].l].mn[j]);
}
if(t[i].r){
t[i].mx[j]=max(t[i].mx[j], t[t[i].r].mx[j]);
t[i].mn[j]=min(t[i].mn[j], t[t[i].r].mn[j]);
}
}
}

void kd_maketree(int L, int R, int now){
t[l].l=t[l].r=0;
D=now; int mid=(L+R)>>1;
nth_element(a+L, a+mid, a+R+1);
t[l].d[0]=a[mid].d[0]; t[l].d[1]=a[mid].d[1]; t[l].x=a[mid].x;
int l1=l;
if(L<mid){l++; t[l1].l=l; kd_maketree(L, mid-1, now^1);}
if(mid<R){l++; t[l1].r=l; kd_maketree(mid+1, R, now^1);}
update(l1);
}

void kd_ins(int i, int x, int y, int z, int now, int fa, int p){
if(!i){
t[++l].d[0]=x; t[l].d[1]=y; t[l].x=z; update(l);
if(!p)t[fa].l=l; else t[fa].r=l;
return;
}
if(t[i].d[0]==x&&t[i].d[1]==y){t[i].x+=z; t[i].sum+=z; return;}
if(!now){
if(x<=t[i].d[0])kd_ins(t[i].l, x, y, z, now^1, i, 0);
else kd_ins(t[i].r, x, y, z, now^1, i, 1);
}else{
if(y<=t[i].d[1])kd_ins(t[i].l, x, y, z, now^1, i, 0);
else kd_ins(t[i].r, x, y, z, now^1, i, 1);
}
update(i);
}

int in(int X1, int X2, int Y1, int Y2){
if(x1<=X1&&X2<=x2&&y1<=Y1&&Y2<=y2)return 1;
return 0;
}
int out(int X1, int X2, int Y1, int Y2){
if(X2<x1||x2<X1||Y2<y1||y2<Y1)return 1;
return 0;
}
void check(int i){
if(!i)return;
if(in(t[i].mn[0], t[i].mx[0], t[i].mn[1], t[i].mx[1])){lastans+=t[i].sum; return;}
if(out(t[i].mn[0], t[i].mx[0], t[i].mn[1], t[i].mx[1]))return;
if(in(t[i].d[0], t[i].d[0], t[i].d[1], t[i].d[1]))lastans+=t[i].x;
check(t[i].l); check(t[i].r);
}

int main(){
m=read(); lastans=0;
l=n=0; B=10000; temp=read();
while(temp<3){
if(temp==1){
n++; a
.d[0]=read()^lastans; a
.d[1]=read()^lastans; a
.x=read()^lastans;
if(!l){
l++; t[l].l=t[l].r=0;
t[l].d[0]=a
.d[0]; t[l].d[1]=a
.d[1]; t[l].x=a
.x;
update(l);
}else kd_ins(1, a
.d[0], a
.d[1], a
.x, 0, 0, 0);
if(n==B){
l=1; kd_maketree(1, n, 0);
B+=10000;
}
}else{
x1=read()^lastans; y1=read()^lastans; x2=read()^lastans; y2=read()^lastans;
lastans=0; check(1); printf("%d\n", lastans);
}
temp=read();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: