【27.77%】【BZOJ 4066】简单题
来源:互联网 发布:大学生有多少存款知乎 编辑:程序博客网 时间:2024/05/21 21:45
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
1 2 3 3
2 1 1 3 3
1 1 1 1
2 1 1 0 7
3
Sample Output
3
5
5
HINT
数据规模和约定
1<=N<=500000,操作数不超过200000个,内存限制20M,保证答案在int范围内并且解码之后数据仍合法。
样例解释见OJ2683
新加数据一组,但未重测----2015.05.24
Source
By wjy1998
【题解】
在做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);elseinsert(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].vif (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);elset[m].l = 0;if (m < end)t[m].r = build(m + 1, end, 1 - fx);elset[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);}elseif (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);}elsebreak;}}int main(){//freopen("F:\\rush.txt", "r", stdin);input_data();return 0;}
0 0
- 【27.77%】【BZOJ 4066】简单题
- [BZOJ 4066]简单题
- bzoj 4066: 简单题
- BZOJ 4066: 简单题 kdtree
- bzoj 4066: 简单题 k-d tree
- [KD-TREE] BZOJ 4066 简单题
- bzoj 4066: 简单题 (KD-tree)
- 【bzoj 3687】: 简单题
- bzoj 2683: 简单题
- BZOJ 2683 简单题
- bzoj 2683 简单题
- BZOJ 3687: 简单题
- BZOJ 2683 简单题
- bzoj 2683: 简单题
- bzoj 3687 简单题|bitset
- BZOJ 2683/4066(简单题-kd-tree重构)
- bzoj 4066: 简单题 带部分重构的KDtree
- 【BZOJ】【P3687】【简单题】【题解】【bitset】
- 零碎知识点总结
- 关于时间复杂度
- DIP关键算法-去噪算法评价标准
- LeetCode[290] Word Pattern
- 51nod 1402 最大值(贪心)
- 【27.77%】【BZOJ 4066】简单题
- Java 高效压缩zip
- Ubuntu 下安装xgboost
- android View的三个构造方法 简单总结
- SpringMVC使用(1) 拦截器
- Struts2.5.2简单的使用注解
- [Leetcode] Jump Game II
- ubuntu开机自动启动
- Struts2.0学习笔记---plainText