Description

你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:
 

命令

参数限制

内容

1 x y A

1<=x,y<=N,A是正整数

将格子x,y里的数字加上A

2 x1 y1 x2 y2

1<=x1<= x2<=N

1<=y1<= y2<=N

输出x1 y1 x2 y2这个矩形内的数字和

3

终止程序

Input

输入文件第一行一个正整数N。
接下来每行一个操作。每条命令除第一个数字之外,
均要异或上一次输出的答案last_ans,初始时last_ans=0。

Output

对于每个2操作,输出一个对应的答案。

Sample Input

4
1 2 3 3
2 1 1 3 3
1 1 1 1
2 1 1 0 7
3

Sample Output

3
5

HINT

数据规模和约定
1<=N<=500000,操作数不超过200000个,内存限制20M,保证答案在int范围内并且解码之后数据仍合法。

Solution

因为把1写成2挂了半天没找到错误ummm……
其他操作都是K-D Tree常规操作,唯一需要改改的就是查询的时候,
若当前KDT节点子树的矩形范围在查询范围外面就return
若当前KDT节点子树的矩形范围全在查询范围里面就统计子树答案return
记得判断一下查询的时候经过的叶子节点是否符合条件,符合则统计一下

Code

 #include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define N (200000+1000)
using namespace std; int n,opt,x,y,X[],Y[],k,D,Root,ans,lastans;
int stack[N],top,cnt;
double alpha=0.75; int NewNode()
{
if (top) return stack[top--];
return ++cnt;
} struct Node
{
int d[],Max[],Min[],lson,rson,sum,val,size;
bool operator < (const Node &a) const {return d[D]<a.d[D];}
Node (int x=,int y=,int z=)
{
d[]=x; d[]=y; lson=rson=; sum=val=z; size=;
Max[]=Min[]=d[]; Max[]=Min[]=d[];
}
}p[N]; struct KDT
{
Node Tree[N]; void Update(int now)
{
int ls=Tree[now].lson, rs=Tree[now].rson;
for (int i=; i<=; ++i)
{
Tree[now].Max[i]=Tree[now].Min[i]=Tree[now].d[i];
if (ls)
{
Tree[now].Max[i]=max(Tree[now].Max[i],Tree[ls].Max[i]);
Tree[now].Min[i]=min(Tree[now].Min[i],Tree[ls].Min[i]);
}
if (rs)
{
Tree[now].Max[i]=max(Tree[now].Max[i],Tree[rs].Max[i]);
Tree[now].Min[i]=min(Tree[now].Min[i],Tree[rs].Min[i]);
}
}
Tree[now].sum=Tree[ls].sum+Tree[rs].sum+Tree[now].val;
Tree[now].size=Tree[ls].size+Tree[rs].size+;
}
int Build(int opt,int l,int r)
{
if (l>r) return ;
int mid=(l+r)>>, now=NewNode();
D=opt; nth_element(p+l,p+mid,p+r+);
Tree[now]=p[mid];
Tree[now].lson=Build(opt^,l,mid-);
Tree[now].rson=Build(opt^,mid+,r);
Update(now); return now;
}
void Dfs(int now,int num)
{
int ls=Tree[now].lson, rs=Tree[now].rson;
if (ls) Dfs(ls,num);
p[num+Tree[ls].size]=Tree[now]; stack[++top]=now;
if (rs) Dfs(rs,num+Tree[ls].size+);
}
void Check(int &now,int opt)
{
int ls=Tree[now].lson, rs=Tree[now].rson;
if (Tree[ls].size>Tree[now].size*alpha || Tree[rs].size>Tree[now].size*alpha)
Dfs(now,), now=Build(opt,,Tree[now].size);
}
void Insert(int &now,int x,int opt)
{
if (now==){Root=x; return;}
if (Tree[x].d[opt]<=Tree[now].d[opt])
{
if (Tree[now].lson) Insert(Tree[now].lson,x,opt^);
else Tree[now].lson=x;
}
else
{
if (Tree[now].rson) Insert(Tree[now].rson,x,opt^);
else Tree[now].rson=x;
}
Update(now); Check(now,opt);
}
void Query(int now)
{
if (Tree[now].Max[]<X[] || Tree[now].Max[]<Y[] || Tree[now].Min[]>X[] || Tree[now].Min[]>Y[]) return;
if (Tree[now].Max[]<=X[] && Tree[now].Min[]>=X[] && Tree[now].Max[]<=Y[] && Tree[now].Min[]>=Y[])
{
ans+=Tree[now].sum;
return;
}
if (Tree[now].d[]<=X[] && Tree[now].d[]>=X[] && Tree[now].d[]<=Y[] && Tree[now].d[]>=Y[]) ans+=Tree[now].val;
if (Tree[now].lson) Query(Tree[now].lson);
if (Tree[now].rson) Query(Tree[now].rson);
}
}KDT; int main()
{
scanf("%d",&n);
while ()
{
scanf("%d",&opt);
if (opt==)
{
scanf("%d%d%d",&x,&y,&k);
x^=lastans; y^=lastans; k^=lastans;
int t=NewNode();
KDT.Tree[t]=Node(x,y,k);
KDT.Tree[t].size=;
KDT.Insert(Root,t,);
}
if (opt==)
{
scanf("%d%d%d%d",&X[],&Y[],&X[],&Y[]);
X[]^=lastans; Y[]^=lastans;
X[]^=lastans; Y[]^=lastans;
ans=;
KDT.Query(Root);
printf("%d\n",ans);
lastans=ans;
}
if (opt==) break;
}
}

BZOJ4066:简单题(K-D Tree)的更多相关文章

  1. [BZOJ2683][BZOJ4066]简单题

    [BZOJ2683][BZOJ4066]简单题 试题描述 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作: 命令 参数限制 内容 1 x y A 1<=x ...

  2. bzoj4066: 简单题 K-Dtree

    bzoj4066: 简单题 链接 bzoj 思路 强制在线.k-dtree. 卡常啊.空间开1e6就T了. 代码 #include <bits/stdc++.h> #define my_m ...

  3. BZOJ4066 简单题(KD-Tree)

    板子题. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  4. Bzoj4066 简单题

    Time Limit: 50 Sec  Memory Limit: 20 MBSubmit: 2185  Solved: 581 Description 你有一个N*N的棋盘,每个格子内有一个整数,初 ...

  5. 简单题(K-D Tree)

    简单题不简单-- 我们把单点加操作改成插入一个权值为增加量的点,将问题转化成询问一个矩阵中所有点的和,用 \(K-D\ Tree\) 维护,时间复杂度 \(O(n\sqrt{n})\) \(Code\ ...

  6. Luogu P4148 简单题(K-D Tree)

    题面 题解 因为强制在线,所以我们不能$cdq$分治,所以考虑用$KDT$,$KDT$维护一个矩阵,然后询问的时候如果当前矩形在询问区间内,直接记贡献,否则判断当前点是否在矩阵内,然后左右分别递归下去 ...

  7. 【kd-tree】bzoj4066 简单题

    同p1176. #include<cstdio> #include<cmath> #include<algorithm> using namespace std; ...

  8. [bzoj4066/2683]简单题_KD-Tree

    简单题 bzoj-4066 题目大意:n*n的棋盘,开始为均为0,支持:单点加权值,查询矩阵权值和,强制在线. 注释:$1\le n\le 5\cdot 10^5$,$1\le m \le 2\cdo ...

  9. 【BZOJ4066】简单题(KD-Tree)

    [BZOJ4066]简单题(KD-Tree) 题面 BZOJ 题解 如果这题不卡空间,并且不强制在线的话 显然可以用\(CDQ\)分治做 但是它又卡空间又强制在线,于是我们欢快的来用\(KD-Tree ...

随机推荐

  1. (转)在 Windows 上调优 DB2 数据库的八个简单步骤

    原文:https://www.ibm.com/developerworks/cn/data/library/techarticle/dm-1209tunedb2/index.html 概述 为了更好地 ...

  2. Developing crm service based on apache cxf

    1 数据库环境搭建 创建数据库boscrm 执行脚本: 脚本内容: /* Navicat MySQL Data Transfer Source Server : root Source Server ...

  3. 移动开发:Android官方提供的支持不同屏幕大小的全部方法

    转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/8830286 原文地址为:http://developer.android.com/ ...

  4. c#合并字典

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  5. node.js压缩和解压缩

    推荐一个极其简单.及其好用的node.js的压缩和解压缩类库  compressing 支持格式: tar.gzip.tgz.zip 以zip为例,tar,tgz和gzip与zip相同. 压缩文件: ...

  6. jquery 获取easyui combobox选中的值、赋值

    jquery easyui combobox 控件支持单选和多选 1.获取选中的值 $('#comboboxlist').combobox('getValue');  //单选时 $('#combob ...

  7. 融云会话界面导航上移-使用IQKeyboardManager

    关于IQKeyBoardManager挤出导航栏的解决方案 方法一: 写在前面 虽然修改后能解决导航栏被挤出去的问题,但是就目前来看是有副作用的,写这篇文章就是想大家来一起讨论,毕竟键盘处理还是比较头 ...

  8. Java - > for, while 及 do.while循环

    为什么要用到循环结构: 按顺序结构执行程序语句(方法或者代码块)只能被执行一次.如果要多次执行,就需要使用到循环结构(循环结构是指在程序中需要反复执行某个功能而设置的一种程序结构) 布尔表达式:是一段 ...

  9. hibernate从零开始到各种映射

    ORM(对象/关系数据库映射) 对象关系映射(Object Relational Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.它完成了面向对象的编程语言到 ...

  10. css rgba/hsla知识点讲解及半透明边框

    一.RGBA(R,G,B,A) 参数: R:红色值.正整数 | |百分数 G:绿色值.正整数 | |百分数 B:蓝色值.正整数 | |百分数 A:Alpha透明度.取值0~1之间. 说明:此色彩模式与 ...