4066: 简单题

Time Limit: 50 Sec  Memory Limit: 20 MB
Submit: 2373  Solved: 622
[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

By wjy1998

[Submit][Status][Discuss]

记得BZOJ还有两道题和这个题是一个意思,但是略有不同。

这道题有两个地方需要注意:

1. 数据通过一定方式强制在线

2. 内存限制只有20M,二维数据结构基本被终结

显然是KD-Tree了,而且需要定期重建以保持其优秀的性质。看到有的题解没有重建就AC了,大概新加数据有卡这类程序,亦或者是大佬的KD-Tree十分优美吧,我等蒟蒻并无此功底……

因为数据以3作为输入终止信号,一开始并不知道有多少操作,也不知道操作是什么,我也懒得先存起来统计操作次数,所以需要找一个合适的重建限度,及进行多少次插入操作后,重建整个KD-Tree。要来数据在本地试了几个数字,发现这个限度取1500~2000较为合适(我一开始猜了个500,直接TLE了),虽然OJ和本地的测试环境有些差距吧,但还是可以作为参考,小伙伴可以像我一样取1700,OJ上跑了30S。

  1 #include <cstdio>
  2 #include <algorithm>
  3
  4 inline int getint(void)
  5 {
  6     int r = 0, f = 0, c = getchar();
  7
  8     for (; c < 48; c = getchar())
  9         if (c == '-')f ^= 1;
 10
 11     for (; c > 47; c = getchar())
 12         r = r * 10 + c - 48;
 13
 14     return f ? -r : r;
 15 }
 16
 17 const int siz = 200005;
 18
 19 struct node
 20 {
 21     int val;
 22     int sum;
 23     int pos[2];
 24     int son[2];
 25     int mini[2];
 26     int maxi[2];
 27
 28     inline void setup(int x, int y, int v)
 29     {
 30         val = sum = v;
 31         son[0] = son[1] = 0;
 32         pos[0] = mini[0] = maxi[0] = x;
 33         pos[1] = mini[1] = maxi[1] = y;
 34     }
 35 }tr[siz]; int tot;
 36
 37 inline void update(int t)
 38 {
 39     tr[t].sum = tr[t].val;
 40
 41     if (tr[t].son[0])
 42         tr[t].sum += tr[tr[t].son[0]].sum;
 43     if (tr[t].son[1])
 44         tr[t].sum += tr[tr[t].son[1]].sum;
 45
 46     tr[t].mini[0] = tr[t].maxi[0] = tr[t].pos[0];
 47     tr[t].mini[1] = tr[t].maxi[1] = tr[t].pos[1];
 48
 49     for (int i = 0; i < 2; ++i)if (tr[t].son[i])
 50         for (int j = 0; j < 2; ++j)
 51         {
 52             if (tr[t].mini[j] > tr[tr[t].son[i]].mini[j])
 53                 tr[t].mini[j] = tr[tr[t].son[i]].mini[j];
 54             if (tr[t].maxi[j] < tr[tr[t].son[i]].maxi[j])
 55                 tr[t].maxi[j] = tr[tr[t].son[i]].maxi[j];
 56         }
 57 }
 58
 59 void insert(int &t, int p, int k)
 60 {
 61     if (!t)t = p;
 62     else
 63     {
 64         if (tr[p].pos[k] <= tr[t].pos[k])
 65             insert(tr[t].son[0], p, k ^ 1);
 66         else
 67             insert(tr[t].son[1], p, k ^ 1);
 68
 69         update(t);
 70     }
 71 }
 72
 73 int cmpk;
 74
 75 inline bool cmp(const node &a, const node &b)
 76 {
 77     if (a.pos[cmpk] != b.pos[cmpk])
 78         return a.pos[cmpk] < b.pos[cmpk];
 79     else
 80         return a.pos[cmpk^1] < b.pos[cmpk^1];
 81 }
 82
 83 int build(int l, int r, int k)
 84 {
 85     int mid = (l + r) >> 1; cmpk = k;
 86
 87     std::nth_element(tr + l, tr + mid, tr + r + 1, cmp);
 88
 89     tr[mid].son[0] = l < mid ? build(l, mid - 1, k ^ 1) : 0;
 90     tr[mid].son[1] = r > mid ? build(mid + 1, r, k ^ 1) : 0;
 91
 92     return update(mid), mid;
 93 }
 94
 95 int x1, y1, x2, y2, ans;
 96
 97 inline bool none(int t)
 98 {
 99     return
100         x1 > tr[t].maxi[0]
101     ||  x2 < tr[t].mini[0]
102     ||  y1 > tr[t].maxi[1]
103     ||  y2 < tr[t].mini[1];
104 }
105
106 inline bool have(int t)
107 {
108     return
109         x1 <= tr[t].mini[0]
110     &&  x2 >= tr[t].maxi[0]
111     &&  y1 <= tr[t].mini[1]
112     &&  y2 >= tr[t].maxi[1];
113 }
114
115 inline bool in(int t)
116 {
117     return
118         x1 <= tr[t].pos[0]
119     &&  x2 >= tr[t].pos[0]
120     &&  y1 <= tr[t].pos[1]
121     &&  y2 >= tr[t].pos[1];
122 }
123
124 void query(int t)
125 {
126     if (none(t))return;
127     if (have(t))ans += tr[t].sum;
128     else
129     {
130         if (in(t))ans += tr[t].val;
131         if (tr[t].son[0])query(tr[t].son[0]);
132         if (tr[t].son[1])query(tr[t].son[1]);
133     }
134 }
135
136 signed main(void)
137 {
138 //    freopen("simple.in", "r", stdin);
139 //    freopen("simple.out", "w", stdout);
140
141     int n = getint(), root = ++tot;
142
143     tr[root].setup(n >> 1, n >> 1, 0);
144
145     while (true)
146     {
147         int k = getint();
148
149         if (k == 1)
150         {
151             int x = getint() ^ ans;
152             int y = getint() ^ ans;
153             int v = getint() ^ ans;
154
155             tr[++tot].setup(x, y, v);
156
157             if (tot % 1700)
158                 insert(root, tot, 0);
159             else
160                 root = build(1, tot, 0);
161         }
162         else if (k == 2)
163         {
164             x1 = getint() ^ ans;
165             y1 = getint() ^ ans;
166             x2 = getint() ^ ans;
167             y2 = getint() ^ ans;
168
169             ans = 0; query(root);
170
171             printf("%d\n", ans);
172         }
173         else break;
174     }
175
176 //    fclose(stdin);
177 //    fclose(stdout);
178 }
179
180 /*
181 2000 : 18.02
182 1800 : 17.22
183 1700 : 16.89
184 1500 : 17.74
185 1000 : 20.80
186 900  : 22.53
187 700  : 25.08
188 500  : 33.55
189 300  : T L E
190 */

@Author: YouSiki

转载于:https://www.cnblogs.com/yousiki/p/6285500.html

BZOJ 4066: 简单题相关推荐

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

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

  2. cdq分治(bzoj 1176: [Balkan2007]Mokia bzoj 2683: 简单题)

    CDQ分治: 本质:对询问进行分治 优点:和莫队分块一样都属于技巧,关键时刻能免去复杂的数据结构,常数小 缺点:必须离线 参考:http://blog.csdn.net/hbhcy98/article ...

  3. Bzoj 2683: 简单题(CDQ分治)

    2683: 简单题 Time Limit: 50 Sec Memory Limit: 20M. Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两 ...

  4. BZOJ 3687 简单题

    3687: 简单题 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 1073  Solved: 518 [Submit][Status][Discus ...

  5. bzoj 3687: 简单题

    2333,昨天模拟赛第一题死都想不出怎么优化tarjan,然而正解是一个kora***什么什么的东西,就是正反两遍dfs,然后这个算法求强联通分量的话,是可以用bitset来优化一下的(只考虑点). ...

  6. bzoj2683/4066 简单题

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2683 http://www.lydsy.com/JudgeOnline/problem.ph ...

  7. bzoj2683:简单题(树状数组套CDQ分分治)

    CDQ(陈丹琦)分治 CDQ显然是一个人的名字(2008NOI金牌选手陈丹琦) 这种离线的分治算法在算法界被称为"CDQ分治".  首先回忆一下归并排序的分治, 它的操作是将数组二 ...

  8. HDU 排名(简单题)

    好久没在oj上做题了,刚开始第二天做一道简单题的心得记录. 1 #include <cstdio> 2 #include <cstring> 3 #include <st ...

  9. (每日一题)CF1139D Steps to One 2021年天梯赛 L3-3 可怜的简单题(期望,莫比乌斯反演,杜教筛)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 一周连考三门,人都没了 Weblink 2021年天梯赛 L3-3 可怜的简单题 CF1139D Pr ...

最新文章

  1. LeetCode 230. Kth Smallest Element in a BST--C++,Python解法--面试真题--找二叉树中第K小的元素
  2. python做项目看板_三、使用python数据仓库实现可视化看板
  3. 今天你们表现的真棒!!!
  4. matlab 未定义mat2gray,matlab中mat2gray函数用法
  5. sqlite查询空日期类型_SQLite比较日期
  6. crontab定时任务不生效问题解决
  7. python点击网页按钮 没有id_button没有id,没有onclick事件。点击却有提交的功能,如何实现的?...
  8. android switch控件的大小,关于Android Action Bar 上的 Switch控件
  9. handler 与message的一些理解
  10. 学习Java心得体会
  11. UA OPTI570 量子力学 角动量 公式与结论总结
  12. 使用vcpkg安装cgal前安装yasm报错
  13. 用Windows Media Service打造的流媒体直播系统
  14. 使用Android Studio和阿里云数据库实现一个远程聊天程序
  15. Unity显示360度全景照片
  16. (一)大彩屏幕 进行串口通信
  17. Cannot checkout from svn: svn: E155000: ‘XXX‘ is alrea
  18. 解决电脑问题方案之一
  19. html语义化标签是什么,HTML语义化标签探析
  20. [EXCEL] 用excel做动态仪表盘,so easy~

热门文章

  1. pcb外观维修_PCB电路板维修的一些常用技法
  2. mupdf不支持x64_x86平台转x64平台关于内联汇编不再支持的解决
  3. php管理员登录文件,快速的事情,只有管理员,PHP才能访问文件
  4. 瞬时极性法对正负反馈的判断方法_直流电焊机正负极判断方法
  5. 使用Qt创建XML文档及XML文档的增删改
  6. mysql 表资源,MySQL 复制表的方法
  7. [BZOJ 1012] 最大数maxnumber
  8. Codeforces 576D Flights for Regular Customers (图论、矩阵乘法、Bitset)
  9. mysql幻读和不可重复读的区别_面试官:MySQL的可重复读级别能解决幻读吗
  10. android studio标题怎么改,如何在Android Studio中将应用标题更改为徽标