Time Limit: 50 Sec  Memory Limit: 20 MB

Submit: 1919  Solved: 533

[Submit][Status][Discuss]

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范围内并且解码之后数据仍合法。
样例解释见OJ2683
新加数据一组,但未重测----2015.05.24

Source

【题解】

在做kd-tree的时候会记录这个子树的最大矩形范围。如果整个最大矩形范围都在所求的矩形范围内。就直接返回这个最大矩形所在的子树的和。

如果不满足的话就看看当前节点是否在所求矩形内。

如果在就先累加这个节点的。

再递归求解左子树和右子树;

然后加的那组数据会卡时.

要不定时重建整棵树。(10000为周期)

【代码】

#include <cstdio>
#include <algorithm> const int MAXN = 209000; using namespace std; struct point
{
int d[2], ma_x[2], mi_n[2], l, r, sum, v;
}; int n, la = 0, v, root = 0, totn, a1, b1, a2, b2, now;
point t[MAXN], op; void up_data(int rt)
{
int l = t[rt].l, r = t[rt].r;
for (int i = 0; i <= 1; i++)
{
if (l)
{
t[rt].ma_x[i] = max(t[l].ma_x[i], t[rt].ma_x[i]);
t[rt].mi_n[i] = min(t[l].mi_n[i], t[rt].mi_n[i]);
}
if (r)
{
t[rt].ma_x[i] = max(t[r].ma_x[i], t[rt].ma_x[i]);
t[rt].mi_n[i] = min(t[r].mi_n[i], t[rt].mi_n[i]);
}
}
t[rt].sum = t[l].sum + t[r].sum + t[rt].v;//重建后要更新sum值。
} void insert(int &rt, int fx)
{
if (rt == 0) //创节点。更新信息
{
rt = ++totn;
t[rt] = op;
t[rt].l = t[rt].r = 0;
for (int i = 0; i <= 1; i++)
t[rt].ma_x[i] = t[rt].mi_n[i] = t[rt].d[i];
t[rt].sum = v;
t[rt].v = v;
return;
}
else
{
if (op.d[fx] <= t[rt].d[fx])
insert(t[rt].l, 1 - fx);
else
insert(t[rt].r, 1 - fx);
}
up_data(rt);
} int query(int rt, int fx)
{
if (!rt) return 0;
if (op.mi_n[0] <= t[rt].mi_n[0] && t[rt].ma_x[0] <= op.ma_x[0] &&
op.mi_n[1] <= t[rt].mi_n[1] && t[rt].ma_x[1] <= op.ma_x[1])
return t[rt].sum; //整个子树都在范围内
int temp = 0, l = t[rt].l, r = t[rt].r;
if (op.mi_n[0] <= t[rt].d[0] && t[rt].d[0] <= op.ma_x[0] &&
op.mi_n[1] <= t[rt].d[1] && t[rt].d[1] <= op.ma_x[1]) //这个点在范围内
temp += t[rt].sum - t[l].sum - t[r].sum; //减去两个子树的就是当前这个点的
//或直接加t[rt].v
if (op.mi_n[fx] <= t[rt].d[fx])
temp += query(l, 1 - fx);
if (t[rt].d[fx] <= op.ma_x[fx])
temp += query(r, 1 - fx);
return temp;
} bool cmp(point a, point b)
{
if (a.d[now] < b.d[now])
return true;
return false;
} int build(int begin, int end, int fx)
{
int m = (begin + end) >> 1;
now = fx;
nth_element(t + begin, t + m, t + end + 1, cmp);
for (int i = 0; i <= 1; i++)
t[m].ma_x[i] = t[m].mi_n[i] = t[m].d[i];
t[m].sum = t[m].v;
if (begin < m)
t[m].l = build(begin, m - 1, 1 - fx);
else
t[m].l = 0;
if (m < end)
t[m].r = build(m + 1, end, 1 - fx);
else
t[m].r = 0;
up_data(m);
return m;
} void input_data()
{
scanf("%d", &n);
while (true)
{
int cz;
scanf("%d", &cz);
if (cz == 1)
{
if ((totn != 0) && (totn % 10000) == 0) //重建树
root = build(1, totn, 0);
scanf("%d%d%d", &op.d[0], &op.d[1], &v);
op.d[0] ^= la; op.d[1] ^= la; v ^= la;
insert(root, 0);
}
else
if (cz == 2)
{
scanf("%d%d%d%d", &op.mi_n[0], &op.mi_n[1], &op.ma_x[0], &op.ma_x[1]);
op.mi_n[0] ^= la; op.mi_n[1] ^= la;
op.ma_x[0] ^= la; op.ma_x[1] ^= la;
la = query(root, 0);
printf("%d\n", la);
}
else
break;
}
} int main()
{
//freopen("F:\\rush.txt", "r", stdin);
input_data();
return 0;
}

【27.77%】【BZOJ 4066】简单题的更多相关文章

  1. bzoj 4066: 简单题 kd-tree

    4066: 简单题 Time Limit: 50 Sec  Memory Limit: 20 MBSubmit: 234  Solved: 82[Submit][Status][Discuss] De ...

  2. BZOJ 4066 简单题(KD树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4066 [题目大意] 要求维护矩阵内格子加点和矩阵查询 [题解] 往KD树上加权值点,支 ...

  3. bzoj 4066 简单题——KDtree(带重构)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4066 带部分重构的KDtree.就是那个替罪羊树思想的. 写了对拍,调了半天,发现忘了 re ...

  4. bzoj 4066: 简单题 K-D树

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=4066 题解 我们把每次的修改操作都当作二维平面上多了一个权值点 对于每组询问可以看做求一 ...

  5. BZOJ 4066 简单题 ——KD-Tree套替罪羊树

    [题目分析] 直接x,y二维轮番划分,暴力即可. 套上替罪羊,打碎重构,对于时间复杂度有了保证. 写起来好麻烦,重构的技巧很棒! [代码] #include <cstdio> #inclu ...

  6. bzoj 4066: 简单题

    #include<cstdio> #include<iostream> #include<cstdlib> #include<algorithm> #d ...

  7. BZOJ 2683: 简单题

    2683: 简单题 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 913  Solved: 379[Submit][Status][Discuss] ...

  8. BZOJ 3687: 简单题 bitset

    3687: 简单题 Time Limit: 10 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description 小呆开始研究集合论了,他 ...

  9. bzoj 4066 & bzoj 2683 简单题 —— K-D树(含重构)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4066 https://www.lydsy.com/JudgeOnline/problem.p ...

  10. BZOJ 2683: 简单题(CDQ分治 + 树状数组)

    BZOJ2683: 简单题(CDQ分治 + 树状数组) 题意: 你有一个\(N*N\)的棋盘,每个格子内有一个整数,初始时的时候全部为\(0\),现在需要维护两种操作: 命令 参数限制 内容 \(1\ ...

随机推荐

  1. Spider_req

    requests模块 安装(用管理员身份去打开Anaconda Prompt) conda install requests python -m pip install requests # 以管理员 ...

  2. eclipse git冲突解决

    1.工程->Team->同步: 2.从远程pull至本地,就会出现如下内容: 3.使用Merge Tool,执行第二项 4.再手动修改 4.修改后的文件需要添加到Git index中去: ...

  3. MySQLSocketPHPvimApache

    原文:http://www.blogjava.net/asenyifei/articles/82575.html 自己装了一个MYSQL客户端,但却发现出现这样的错误: Can't connect t ...

  4. GraphX 图数据建模和存储

    背景 简单分析一下GraphX是怎么为图数据建模和存储的. 入口 能够看GraphLoader的函数. def edgeListFile( sc: SparkContext, path: String ...

  5. android对话框(Dialog)的使用方法

    Activities提供了一种方便管理的创建.保存.回复的对话框机制.比如 onCreateDialog(int), onPrepareDialog(int, Dialog), showDialog( ...

  6. nodejs连接mysql突然中断问题解决方案

    db/index.js数据库配置文件 一.在数据库连接失败的情况下,回调函数,再次发起连接,直到连接成功为止. handleDisconnect(){ this.connection.connect( ...

  7. 使用Intent的Flag设置启动參数

    Intent中关于激活Activity的Flag Intent类定义了一批常量,用于配置激活Activity时的相关參数; 在Intent中设置Flag ·调用Intent的setFlags()或ad ...

  8. JS中的发布订阅模式

    一. 你是如何理解发布订阅模式的 JS中的设计模式: 单例模式:处理业务逻辑 构造原型模式:封装类库,组件,框架,插件等 类库:jQuery 只是提供了一些常用的方法,可以应用到任何的项目中,不具备业 ...

  9. CSS笔记 - fgm练习 2-9 - 播放列表收缩展开

    练习地址: http://www.fgm.cc/learn/lesson2/09.html <style> *{ margin: 0;padding: 0;font-size: 12px; ...

  10. 具体解释ebs接口之客户配置文件导入(二)

    ------------------------------------ -- 1a. Setup the Org_id ------------------------------------ ex ...