BZOJ 2683: 简单题 离线+CDQ分治
来源:互联网 发布:淘宝飞机杯哪家好 编辑:程序博客网 时间:2024/05/31 18:30
2683: 简单题
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 381 Solved: 163
[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。
接下来每行一个操作。
Output
对于每个2操作,输出一个对应的答案。
Sample Input
4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
Sample Output
3
5
5
HINT
1<=N<=500000,操作数不超过200000个,内存限制20M。
对于100%的数据,操作1中的A不超过2000。
http://www.lydsy.com/JudgeOnline/problem.php?id=2683
把操作都离线出来,按x为第一关键字,y为第二关键字排序,按照读入顺序标记操作的顺序,在mid表示某个操作的时间,mid左边的操作就会影响mid右边的操作,如此进行cdq分治。查询操作拆成4个子操作。
还要继续巩固!
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define Q q[tot]const int maxn = 800000 +10;struct Node{ int x, y, A, no, belong, op;}q[maxn], tq[maxn];int ans[maxn];bool operator <(Node a, Node b){ if (a.x == b.x && a.y == b.y) return a.op < b.op; if (a.x == b.x) return a.y < b.y; return a.x < b.x;}#define lowbit(x) (x&(-x))int N;int tree[maxn];void update(int x, int v){ while(x <= N){ tree[x] += v; x += lowbit(x); }}int getsum(int x){ int sum = 0; while(x > 0){ sum += tree[x]; x -= lowbit(x); } return sum;}void solve(int l, int r){ if (l == r) return; int mid = (l+r)>>1; for(int i = l ;i <= r; i++){ if (q[i].no <= mid && q[i].op == 1) update(q[i].y, q[i].A); else if (q[i].no > mid && q[i].op == 2){ if (q[i].A){ ans[q[i].belong] += getsum(q[i].y); } else{ ans[q[i].belong] -= getsum(q[i].y); } } } for(int i = l; i <= r; i++){ if (q[i].no <= mid && q[i].op == 1) update(q[i].y, -q[i].A); } int l1 = l, l2 = mid + 1; for(int i = l; i <= r; i++){ if (q[i].no <= mid) tq[l1++] = q[i]; else tq[l2++] = q[i]; } for(int i = l; i <= r; i++){ q[i] = tq[i]; } solve(l, mid); solve(mid+1, r);}int main(){// freopen("data.in", "r", stdin); int T = 0, op, x, y, x1, y1, A, tot = 0; scanf("%d", &N); while(scanf("%d", &op) && op!=3){ if (op == 1){ scanf("%d%d%d", &x, &y, &A); q[++tot].op = 1; Q.x = x; Q.y = y; Q.A = A; Q.no = tot; } else{ scanf("%d%d%d%d", &x, &y, &x1, &y1); q[++tot].op = 2; Q.x = x-1; Q.y = y-1; Q.A = 1; Q.no = tot; Q.belong = ++T; q[++tot].op = 2; Q.x = x-1; Q.y = y1; Q.A = 0; Q.no = tot; Q.belong = T; q[++tot].op = 2; Q.x = x1; Q.y = y-1; Q.A = 0; Q.no = tot; Q.belong = T; q[++tot].op = 2; Q.x = x1; Q.y = y1; Q.A = 1; Q.no = tot; Q.belong = T; } } sort(q+1, q+1+tot); solve(1, tot); for(int i = 1; i <= T; i++){ printf("%d\n", ans[i]); } return 0;}
0 0
- BZOJ 2683: 简单题 离线+CDQ分治
- Bzoj 2683: 简单题(CDQ分治)
- BZOJ 2683: 简单题(CDQ分治)
- BZOJ 2683 简单题 CDQ分治+树状数组
- BZOJ 2683 简单题 cdq分治+树状数组
- BZOJ 1176: [Balkan2007]Mokia&&2683: 简单题|cdq分治
- BZOJ 2683 简单题(CDQ分治+容斥)
- bzoj 2683: 简单题 cdq分治+树状数组
- BZOJ 2683: 简单题【CDQ分治 + 树状数组
- 【BZOJ 2683】简单题 CDQ分治+树状数组
- bzoj 2683: 简单题 (CDQ分治+树状数组)
- [BZOJ]2683: 简单题 CDQ分治+树状数组
- BZOJ 2683 CDQ分治
- cdq分治(bzoj 1176: [Balkan2007]Mokia && bzoj 2683: 简单题)
- BZOJ 1176 && BZOJ 2683 CDQ分治
- 【BZOJ2683】简单题【CDQ分治】
- bzoj 3262(cdq分治)
- bzoj 1176(cdq分治)
- github 使用教程图文详解
- GitHub教程
- Android中的AlarmManager的使用
- Servlet多线程同步问题
- 最简单的java输入输出
- BZOJ 2683: 简单题 离线+CDQ分治
- Spring的单例模式底层实现
- Single Number
- java常用设计模式
- android二维码、条形码分分钟秒杀
- 算法
- 第112讲:为什么会有第一代大数据技术Hadoop和第二代大数据技术Spark?学习笔记
- 给一个不带头结点的单链表,写出将链表倒置的算法
- Java 理论与实践: 描绘线程安全性