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. 28.semaphore跨进程通信

    根据id创建Semaphore,并初始化有一个信号量可用 name类型是char *...; HANDLE hsem = CreateSemaphoreA(NULL, 1, , name); 关闭句柄 ...

  2. 【hdu 3478】Catch

    [Link]:http://acm.hdu.edu.cn/showproblem.php?pid=3478 [Description] 一个人从起点s出发,假设他在时间t在节点x; 则在时间t+1,他 ...

  3. 7.3 GROUP BY的“新”功能

    7.3 GROUP BY的"新"功能正在更新内容,请稍后

  4. Jszip的使用和打包下载图片

    因为canvas总结到后面又想到了jszip的一些事情,那就索性也回去看看吧.试过,至少谷歌和火狐都是支持jszip的. 1.  jszip的使用 官方文档说的很清楚了,而且也有读取zip文件.生成z ...

  5. Node.js笔记 请求方式 GET

    三种方法解析url 1. 传统的字符串split切割方法 2. querystring     只能解析数据部分,不能解析前面 index.html之类的地址部分. 3. url   可以解析地址和数 ...

  6. PythonNET网络编程4

    本地套接字 Linux 文件 b(块设备文件) c(字符设备文件) d(目录) -(普通文件) l(链接) s(套接字) p(管道) 作用:用于本地不同的程序间进行通信 创建流程 创建本地套接字 so ...

  7. 洛谷 P1691 有重复元素的排列问题

    P1691 有重复元素的排列问题 题目描述 设R={r1,r2,……,rn}是要进行排列的n个元素.其中元素r1,r2,……,rn可能相同.使设计一个算法,列出R的所有不同排列. 给定n以及待排列的n ...

  8. Linux CentOS PhpMyAdmin安装--转载

    原文地址:https://www.centos.bz/2011/04/linux-centos-phpmyadmin-install/ 安装好PHP,Apache和MySQL程序后,为了管理MySQL ...

  9. (win7/8/10)鼠标右键添加按下SHIFT键时弹出带管理员权限的“在此处打开命令窗口”

    Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Directory\Background\shell\runas]@="@sh ...

  10. 关于python的拷贝

    https://blog.csdn.net/koukehui0292/article/details/82993958 Python的 深度拷贝: import copy d=copy.deepcop ...