2683: 简单题

Time Limit: 50 Sec  Memory Limit: 128 MB
Submit: 913  Solved: 379
[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

Sample Output

3
5

HINT

1<=N<=500000,操作数不超过200000个,内存限制20M。
对于100%的数据,操作1中的A不超过2000。

Source

 

[Submit][Status][Discuss]

分析

离线CDQ分治,对于预处理后的所有操作(查询)按照X坐标排序,然后用树状数组维护Y坐标上的前缀和。

代码

 #include <bits/stdc++.h>

 using namespace std;

 const int N = ;
const int M = ; template <class T>
__inline void read(T &x)
{
x = ;
bool f = false;
char c = getchar(); while (c < '')
{
if (c == '-')
f ^= true;
c = getchar();
} while (c >= '')
{
x = x* + c - '';
c = getchar();
} if (f)x = -x;
} struct operation
{
int id, op, to, x, y, d;
}q[M << ], tmp[M << ]; int cmp(const void *a, const void *b)
{
operation *A = (operation *)a;
operation *B = (operation *)b; if (A->x != B->x)
return A->x - B->x;
if (A->y != B->y)
return A->y - B->y;
return A->op - B->op;
} int n, m, t; void pushQuery(void)
{
int x1; read(x1);
int y1; read(y1);
int x2; read(x2);
int y2; read(y2); ++t;
{
++m;
q[m].d = ;
q[m].op = ;
q[m].id = m;
q[m].to = t;
q[m].x = x1 - ;
q[m].y = y1 - ;
}
{
++m;
q[m].d = ;
q[m].op = ;
q[m].id = m;
q[m].to = t;
q[m].x = x2;
q[m].y = y2;
}
{
++m;
q[m].d = -;
q[m].op = ;
q[m].id = m;
q[m].to = t;
q[m].y = y2;
q[m].x = x1 - ;
}
{
++m;
q[m].d = -;
q[m].op = ;
q[m].id = m;
q[m].to = t;
q[m].x = x2;
q[m].y = y1 - ;
}
} int answer[M]; void printAnswer(void)
{
for (int i = ; i <= t; ++i)
printf("%d\n", answer[i]);
} namespace binaryInsertTree
{
int tree[N]; void change(int p, int v)
{
for (int i = p; i <= n; i += i & -i)
tree[i] += v;
} int query(int p)
{
int ret = ; for (int i = p; i >= ; i -= i & -i)
ret += tree[i]; return ret;
}
} void divideAndConquer(int l, int r)
{
if (l != r)
{
int mid = (l + r) >> ; for (int i = l; i <= r; ++i)
{
if (q[i].op == && q[i].id <= mid)
binaryInsertTree::change(q[i].y, q[i].d);
if (q[i].op == && q[i].id > mid)
answer[q[i].to] += binaryInsertTree::query(q[i].y) * q[i].d;
} for (int i = l; i <= r; ++i)
if (q[i].op == && q[i].id <= mid)
binaryInsertTree::change(q[i].y, -q[i].d); int t1 = l, t2 = mid + ; for (int i = l; i <= r; ++i)
{
if (q[i].id <= mid)
tmp[t1++] = q[i];
else
tmp[t2++] = q[i];
} for (int i = l; i <= r; ++i)
q[i] = tmp[i]; divideAndConquer(l, mid);
divideAndConquer(mid + , r);
}
} signed main(void)
{
read(n); for (m = t = ; ; )
{
int opt; read(opt); if (opt == )break; switch (opt)
{
case :
++m;
q[m].op = ;
q[m].id = m;
read(q[m].x);
read(q[m].y);
read(q[m].d);
break;
case :
pushQuery();
}
} qsort(q + , m, sizeof(operation), cmp); divideAndConquer(, m); printAnswer();
}

BZOJ_2683.cpp

@Author: YouSiki

BZOJ 2683: 简单题的更多相关文章

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

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

  2. BZOJ 2683: 简单题 [CDQ分治]

    同上题 那你为什么又发一个? 因为我用另一种写法又写了一遍... 不用排序,$CDQ$分治的时候归并排序 快了1000ms... #include <iostream> #include ...

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

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

  4. BZOJ 2683 简单题 cdq分治+树状数组

    题意:链接 **方法:**cdq分治+树状数组 解析: 首先对于这道题,看了范围之后.二维的数据结构是显然不能过的.于是我们可能会考虑把一维排序之后还有一位上数据结构什么的,然而cdq分治却可以非常好 ...

  5. BZOJ 2683: 简单题(CDQ 分治)

    题面 Time Limit: 50 Sec  Memory Limit: 128 MB Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作: ...

  6. BZOJ 2683 简单题 ——CDQ分治

    [题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ...

  7. bzoj 1176: [Balkan2007]Mokia&&2683: 简单题 -- cdq分治

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

  8. bzoj 4066: 简单题 kd-tree

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

  9. BZOJ 3687: 简单题 bitset

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

随机推荐

  1. JS 中如何判断字符串类型的数字

    function isNumberStr(str){ var n = Number(str); return !isNaN(n); } console.log(isNumberStr('37')); ...

  2. iOS多线程开发

    概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操 ...

  3. css position, display, float 内联元素、块级元素

    position属性:position属性指出一个元素的定位方法.有4种可能值:static, relative, absolute or fixed: static:默认值,元素按照在文档流中出现的 ...

  4. M3U8格式讲解及实际应用分析

    M3U8格式讲解及实际应用分析 M3U8有啥好处 ? 网上搜索了一下,大家众说纷纭,个人理解主要是可以做多码率的适配,根据网络带宽,客户端会选择一个适合自己码率的文件进行播放,保证视频流的流畅. 在I ...

  5. 欢迎访问我的视频网站&音乐网站

    写博客有时是有缺陷的,有些事情写起来是不容易说清楚的.所以我以后会录制一些视频.欢迎访问啦 视频地址  http://www.tudou.com/home/quan8b/ 我的个人音乐站 http:/ ...

  6. bootstrap-datepicker带中文的js文件

    ) { $(".datepicker").datepicker({ language: "zh-CN", autoclose: true,//选中之后自动隐藏日 ...

  7. linux命令行安装使用KVM

    一.说明 本篇文章介绍的是基于centos环境来安装的,ip地址192.168.4.233 二.检查CPU是否支持虚拟技术 egrep 'vmx|svm' /proc/cpuinfo 如果有输出内容表 ...

  8. 在线程中调用SaveFileDialog

    在多线程编程中,有时候可能需要在单独线程中执行某些操作.例如,调用SaveFileDialog类保存文件.首先,我们在Main方法中创建了一个新线程,并将其指向要执行的委托SaveFileAsyn.在 ...

  9. C#迭代器

    迭代器概述 迭代器是可以返回相同类型的值的有序序列的一段代码. 迭代器可用作方法.运算符或 get 访问器的代码体. 迭代器代码使用 yield return 语句依次返回每个元素.yield bre ...

  10. JavaScript面试题收集(一)

    简述javascript中的“=.==.===”的区别? 答:=赋值 ==比较是否一般相等   "3"==3 //会做类型的隐式转换,true ===比较是否严格相等 " ...