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;
}
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;
}
相关文章推荐
- Hibernate中get和load的区别
- Material Design风 第二话(CollapsingToolbarLayout+AppBarLayout+NestedScrollView)
- Npgsql使用入门(三)【批量导入数据】
- Sqli-LABS通关笔录-17-审计SQL注入
- django学习——url的name
- unique-substrings-in-wraparound-string(好)
- Spring 框架知识知识总结
- 笔记---手动排序
- 数据库异地备份还原
- Spannable
- PTA数据结构与算法题目集(中文)4-10 二分查找 (20分)
- GridBagLayout练习
- 各种排序算法的java实现及时间、空间复杂度、稳定程度总结
- Add Strings
- 678.最小K个数之和
- CSS3属性transform详解之(旋转:rotate,缩放:scale,倾斜:skew,移动:translate)
- "科林明伦杯"哈尔滨理工大学第六届程序设计团队赛
- 我叫标题
- grub循环 无法启动win10
- Windows Server 2012 启用网络共享失败