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. protobuf参考

    https://www.cnblogs.com/chenyangyao/p/5422044.html

  2. Ionic3,关于配置公共的css文件,引用非标准的文件(三)

    说明 在开发过程中,很多样式为了能够共用,这样能够节省很大一部分时间用来编写样式,同时,一个完整的共用模板,在进行样式更换的时候,可以达到事半功倍的效果,因此在开发效率上也可以获得提高. 相关步骤: ...

  3. 0325img和超链接的学习

    上午学习了cellspacing\cellpadding,img标签以及三种属性,src,alt,title.下午学习了超链接<a></a>,绝对路径与相对路径,锚点链接的使用 ...

  4. (转)2017年最新企业面试题之shell(一,二)

    2017年最新企业面试题之shell(一) ********************************************** 企业Shell面试题1:批量生成随机字符文件名案例 * *** ...

  5. 15019:Only the instance admin may alter the PermSize attribute

    15019:Only the instance admin may alter the PermSize attribute TimesTen提示空间不足,增加空间重启后提示15019:Only th ...

  6. TOJ 4289 Unrequited Love

    Description There are n single boys and m single girls. Each of them may love none, one or several o ...

  7. RabbitMQ学习整理

    1.什么是消息队列? 概念: 消息队列(Message Queue,简称MQ),本质是个队列,FIFO先入先出,只不过队列中存放的内容是一些Message. 2.为什么要用消息队列,应用场景? 不同系 ...

  8. 使用 GitHub API 进行数据分析 (Node.js)

    使用 GitHub API 进行数据分析 (Node.js) Node.js 的访问 GitHub 的 API 库,通过 npm 或者 yarn 安装: yarn add github-api 官方示 ...

  9. BNU29140——Taiko taiko——————【概率题、规律题】

    Taiko taiko Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class ...

  10. Django(5) session登录注销、csrf及中间件自定义、django Form表单验证(非常好用)

    一.Django中默认支持Session,其内部提供了5种类型的Session供开发者使用: 数据库(默认) 缓存 文件 缓存+数据库 加密cookie 1.数据库Session 1 2 3 4 5 ...