Bzoj2683 简单题 [CDQ分治]
Time Limit: 50 Sec Memory Limit: 128 MB
Submit: 1071 Solved: 428
Description
命令 |
参数限制 |
内容 |
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
Output
Sample Input
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
Sample Output
5
HINT
Source
CDQ分治
第4遍回顾之前抄的代码的时候,突然顿悟。
个人理解,这种分治方法类似于做矩形面积并时候用到的扫描线法。将每个区间修改操作拆成插入/删除,和每个询问操作一起按横坐标x升序排序。
用一个一维数组记录“当前横坐标”对应的y轴情况,从左往右扫描所有操作,并用差分的方式完成修改(在时间维度上差分),记录答案。
↑该一维数组可以用树状数组优化,扫描操作可以用分治方法优化(每层分治时处理前半部分操作对后半部分查询的影响)。
↑组合起来就成了CDQ分治。
________
PS1: 这时我想起,两三个个月前RLQ说他研究出一种用树状数组乱搞二维大数据的做法,当时没怎么听懂,也没太在意……卧槽,原来是CDQ分治?
CDQ分治要是晚出现两年,就变成RLQ分治了……%%%%%
PS2: 之前抄的LCT也已经回顾了10+遍了,是不是也快要顿悟了呢……
________
/*by SilverN*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n;
struct opt{
int flag;
int x,y,w;
int t;
int id;
}a[mxn*],b[mxn*];
int cnt=;
int cmp(opt q,opt e){
if(q.x==e.x){
if(q.y==e.y)return q.flag<e.flag;
return q.y<e.y;
}
return q.x<e.x;
}
int ans[mxn];
int t[mxn*];
void add(int x,int v){while(x<=n){t[x]+=v;x+=x&-x;}return;}
int sum(int x){
int res=;
while(x){res+=t[x];x-=x&-x;}
return res;
}
void solve(int l,int r){
if(l>=r)return;
int i,j,mid=(l+r)>>;
int l1=l,l2=mid+;
for(i=l;i<=r;i++){
if(a[i].flag== && a[i].t<=mid) add(a[i].y,a[i].w);
else if(a[i].flag== && a[i].t>mid) ans[a[i].id]+=sum(a[i].y)*a[i].w;
}
for(i=l;i<=r;i++)
if(a[i].flag== && a[i].t<=mid) add(a[i].y,-a[i].w);
for(i=l;i<=r;i++)
if(a[i].t<=mid)b[l1++]=a[i];
else b[l2++]=a[i];
for(i=l;i<=r;i++)a[i]=b[i];
solve(l,mid);solve(mid+,r);
return;
}
int main(){
n=read();
int i,j,x,y,c,v;
int id=;
while(){
c=read();
if(c==)break;
if(c==){//修改
x=read();y=read();v=read();
a[++cnt].flag=;a[cnt].x=x;a[cnt].y=y;a[cnt].w=v;
a[cnt].t=cnt;
}
else{//查询
x=read();y=read();c=read();v=read();
a[++cnt].flag=;a[cnt].x=x-;a[cnt].y=y-;
a[cnt].w=;a[cnt].t=cnt;a[cnt].id=++id;
a[++cnt].flag=;a[cnt].x=x-;a[cnt].y=v;
a[cnt].w=-;a[cnt].t=cnt;a[cnt].id=id;
a[++cnt].flag=;a[cnt].x=c;a[cnt].y=y-;
a[cnt].w=-;a[cnt].t=cnt;a[cnt].id=id;
a[++cnt].flag=;a[cnt].x=c;a[cnt].y=v;
a[cnt].w=;a[cnt].t=cnt;a[cnt].id=id;
}
}
sort(a+,a+cnt+,cmp);
solve(,cnt);
for(i=;i<=id;i++){
printf("%d\n",ans[i]);
}
return ;
}
Bzoj2683 简单题 [CDQ分治]的更多相关文章
- bzoj2683简单题 cdq分治
2683: 简单题 Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 1803 Solved: 731[Submit][Status][Discuss] ...
- BZOJ2683: 简单题(cdq分治 树状数组)
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 2142 Solved: 874[Submit][Status][Discuss] Descripti ...
- 【BZOJ1176】[Balkan2007]Mokia/【BZOJ2683】简单题 cdq分治
[BZOJ1176][Balkan2007]Mokia Description 维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=1600 ...
- 【bzoj1176】[Balkan2007]Mokia/【bzoj2683】简单题 CDQ分治+树状数组
bzoj1176 题目描述 维护一个W*W的矩阵,初始值均为S(题目描述有误,这里的S没有任何作用!).每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数 ...
- 【BZOJ-1176&2683】Mokia&简单题 CDQ分治
1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1854 Solved: 821[Submit][St ...
- bzoj 1176: [Balkan2007]Mokia&&2683: 简单题 -- cdq分治
2683: 简单题 Time Limit: 50 Sec Memory Limit: 128 MB Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要 ...
- BZOJ 2683: 简单题 [CDQ分治]
同上题 那你为什么又发一个? 因为我用另一种写法又写了一遍... 不用排序,$CDQ$分治的时候归并排序 快了1000ms... #include <iostream> #include ...
- BZOJ 2683 简单题 cdq分治+树状数组
题意:链接 **方法:**cdq分治+树状数组 解析: 首先对于这道题,看了范围之后.二维的数据结构是显然不能过的.于是我们可能会考虑把一维排序之后还有一位上数据结构什么的,然而cdq分治却可以非常好 ...
- BZOJ 2683: 简单题(CDQ 分治)
题面 Time Limit: 50 Sec Memory Limit: 128 MB Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作: ...
随机推荐
- 1002. A+B for Polynomials
1002. A+B for Polynomials (25) This time, you are supposed to find A+B where A and B are two polynom ...
- DWZ中Tree树形菜单的treeCheck如何获取返回值解决方案
最近在对DWZ和asp.net MVC3进行整合,其中遇到了很多问题,总算一一解决了,今天就说说题目所示的问题解决方案. 想做一个基于角色的权限管理,要对每一个Action进行权限控制.就想用DWZ的 ...
- c++ 指针(二)
函数指针 可以使用算法的地址传递给方法,传递之前要先完成以下工作 1.获取函数的地址 2.声明一个函数指针 3.使用函数指针来调用函数 1.获取函数的地址,只要使用函数名就可以 Fun2(Fun1); ...
- Ajax与json在前后端中的细节解惑
ajax请求JSON Thinkphp中对是否为Ajax的判断,在TP3.2开发手册中有这么一段:“需要注意的是,如果使用的是ThinkAjax或者自己写的Ajax类库的话,需要在表单里面添加一个隐藏 ...
- JQuery fullCalendar 时间差 排序获取距当前最近的时间。
let time = (wo: WoDto) => wo.ScheduleTime || wo.ScheduleStartTime; let wo = technician.wos .filte ...
- [C语言]一个很实用的服务端和客户端进行UDP通信的实例
前段时间发了个TCP通信的例子,现在再来一个UDP通信的例子.这些可以作为样本程序,用到开发中.“裸写”socket老是记不住步骤,经常被鄙视…… 下面的例子很简单,写一个UDP的server用于收包 ...
- Android开发自学笔记(Android Studio1.3.1)—2.开始第一个Android应用
一.前言 使用Android Studio开发Android应用是一件非常简单的事情,因为它会帮你自动完成很多工作.本篇我们主要完成一个单击按钮在文本框显示当前时间的简单应用,借此来演示一下 ...
- WEB API 中HTTP的get、post、put,delete 请求方式
一.WEB API 中HTTP 请求方式的四个主要方法 (GET, PUT, POST, DELETE), 按照下列方式映射为 CURD 操作: 1.POST 用于新建资源,服务端在指定的URI 上创 ...
- [BZOJ1116][Poi2008]LCO(并查集)
题目:http://hzwer.com/3010.html 分析:注意这里无向边是对入度没有贡献的. 那么对于一个n个点的连通块而言,如果它是一颗树(n-1条边),那么把所有边全部从某个根开始向下指, ...
- Map集合的应用及其遍历方式
---> HashMap :底层基于哈希表 存储原理也使用哈希表来存放的: 往HashMap添加了元素 ,首先会调用键的hashCode方法 获得一个哈希值,然后 ...