#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#define maxn 500005
#define maxm 800005
using namespace std; int n,m,cnt,sum[maxn],pos[maxm],ans[maxm];
struct date{
int op,x,y,v,id;
}qs[maxm]; bool comp(date x,date y){
return x.x<y.x;
} int lowbit(int x){
return x&(-x);
} void add(int x,int y){
for (int i=x;i<=n;i+=lowbit(i)){
sum[i]+=y;
}
} int query(int x){
int temp=;
for (int i=x;i>;i-=lowbit(i)){
temp+=sum[i];
}
return temp;
} void cdq_solve(int l,int r){
if (l==r) return;
int mid=(l+r)/,temp=;
cdq_solve(l,mid),cdq_solve(mid+,r);
sort(qs+l,qs+mid+,comp),sort(qs+mid+,qs+r+,comp);
int i=l,j=mid+;
while (j<=r){
while (qs[i].op==&&i<=mid) i++;
while (qs[j].op==&&j<=r) j++;
if (i<=mid&&qs[i].x<=qs[j].x) add(qs[i].y,qs[i].v),i++,temp=i-;
else if (j<=r) ans[qs[j].id]+=query(qs[j].y),j++;
}
for (int t=l;t<=temp;t++) if (qs[t].op==) add(qs[t].y,-qs[t].v);
} int main(){
memset(ans,,sizeof(ans));
memset(sum,,sizeof(sum));
int op,x1,x2,y1,y2;
scanf("%d",&n),m=cnt=;
for (;;){
scanf("%d",&op);
if (op==){
qs[++m].op=op,qs[m].id=m;
scanf("%d%d%d",&qs[m].x,&qs[m].y,&qs[m].v);
}else{
if (op==){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
pos[++cnt]=m;
qs[++m].op=op,qs[m].x=x1-,qs[m].y=y1-,qs[m].id=m;
qs[++m].op=op,qs[m].x=x2,qs[m].y=y2,qs[m].id=m;
qs[++m].op=op,qs[m].x=x1-,qs[m].y=y2,qs[m].id=m;
qs[++m].op=op,qs[m].x=x2,qs[m].y=y1-,qs[m].id=m;
}else break;
}
}
cdq_solve(,m);
for (int i=;i<=cnt;i++) printf("%d\n",ans[pos[i]+]+ans[pos[i]+]-ans[pos[i]+]-ans[pos[i]+]);
}

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2683

题目大意:给定一个n*n的矩形,以及若干个操作,操作有如下两种:

1.给矩形的(x,y)加上一个v;

2.询问某个子矩阵的权值和。

数据范围:n<=5*10^5,操作数<=2*10^5;

初看这题,尼玛这不是二维树状数组(二维线段树也行,不过是作死)傻逼题吗,期望复杂度O(nlog^2 n),空间复杂度n^2,再一看数据范围,GG。

在ls神犇的教导下,我学会了四种通过此题的方法:1.二维线段树动态开点,空间复杂度nlog^2 n),有点卡空间。

2.二维树状数组+hash表,可惜我没掌握这种正确姿势-.-;

3.线段树套平衡树,线段树维护x坐标,每一层套一个splay,以y坐标为关键字,对于一个询问,拆成四个矩阵,再在对应的线段树中在splay中去找,更新答案即可,据说这种写法空间复杂度只有O(n)的复杂度,可以过。

4.进入正题吧,这题的最佳姿势是cdq分治+树状数组维护区间和;

前三种做法略过(在线做法),说说第四种做法(离线做法)吧:

我先来说说cdq_分治的流程吧,cdq分治一般是解决具有一下两种性质的问题(只有修改和查询操作):

1.只能用离线做法。

2.每个修改操作对询问的影响是独立的,即与之前的修改操作无关。

cdq分治与一般的分治不同,一般的分治分出来的子区间是独立的,个个击破即可,而cdq分治分出来的两个子区间是相互联系的。(以下的分治都是指cdq分治)

由于在该问题中,每个询问只与在此之前的修改操作有关。

对于区间l,mid,记为区间1,区间mid+1,r,记为区间2,

过程:

1.递归处理区间(1),

2.递归处理区间(2),

3.统计区间1中的修改操作对区间2中的询问操作的影响。

4.算法结束。

关键在于第3步,对于这个题,我们将两个区间各自按x坐标排序,然后用两个指针分别去扫一遍,遇到区间1中的修改操作,就把纵坐标加入树状数组,然后及时统计区间2中询问的答案即可。具体细节可见代码。

cdq分治+树状数组

bzoj2683简单题的更多相关文章

  1. [BZOJ2683]简单题/[BZOJ1176][BalkanOI2007]Mokia

    [BZOJ2683]简单题 题目大意: 一个\(n\times n(n\le5\times10^5)\)的矩阵,初始时每个格子里的数全为\(0\).\(m(m\le2\times10^5)\)次操作, ...

  2. Bzoj2683 简单题

    Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 1071  Solved: 428 Description 你有一个N*N的棋盘,每个格子内有一个整数, ...

  3. bzoj2683简单题 cdq分治

    2683: 简单题 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 1803  Solved: 731[Submit][Status][Discuss] ...

  4. BZOJ2683: 简单题(cdq分治 树状数组)

    Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 2142  Solved: 874[Submit][Status][Discuss] Descripti ...

  5. BZOJ2683 简单题(CDQ分治)

    传送门 之前听别人说CDQ分治不难学,今天才知道果真如此.之前一直为自己想不到CDQ的方法二很不爽,今天终于是想出来了一道了,太弱-- cdq分治主要就是把整段区间分成两半,然后用左区间的值去更新右区 ...

  6. Bzoj2683 简单题 [CDQ分治]

    Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 1071  Solved: 428 Description 你有一个N*N的棋盘,每个格子内有一个整数, ...

  7. 【对询问分块】【主席树】bzoj2683 简单题

    对操作序列分块,每S次暴力重建主席树. 当S=sqrt(n*log(n))时,复杂度为O(m*sqrt(n*log(n))). 在线的. #include<cstdio> #include ...

  8. cdq分治——bzoj2683简单题

    https://www.lydsy.com/JudgeOnline/problem.php?id=2683 知识点:1.以操作的顺序进行分治  2.cdq分治维护矩阵 3.计算比mid小的给比mid大 ...

  9. [BZOJ2683][BZOJ4066]简单题

    [BZOJ2683][BZOJ4066]简单题 试题描述 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作: 命令 参数限制 内容 1 x y A 1<=x ...

随机推荐

  1. Lobes of the brain

    Source: https://en.wikipedia.org/wiki/Lobes_of_the_brain (Except for the last figure) Terminologia A ...

  2. AlwaysOn--Backup Preference

    AlwaysOn group的一个新特性是允许在secondary replica进行backup,将backup的负载从primary replica上移除去. 并且提供了Backup prefer ...

  3. word里的代码格式,使之有底纹的效果

      实现效果: 怎么才能在word里实现这样的显示? 如何设置word里的代码格式,使之有底纹的效果

  4. 用C++和shell获取本机CPU、网卡IO、内存、磁盘等的基本信息

    用C++和shell获取本机CPU.网卡.内存.磁盘等的基本信息: 由于对C++相关的函数没多少了解,但是觉得用shell反而相对简单一些: 一.shell脚本,用来辅助C++获取主机的资源使用信息 ...

  5. DWZ中Tree树形菜单的treeCheck如何获取返回值解决方案

    最近在对DWZ和asp.net MVC3进行整合,其中遇到了很多问题,总算一一解决了,今天就说说题目所示的问题解决方案. 想做一个基于角色的权限管理,要对每一个Action进行权限控制.就想用DWZ的 ...

  6. JMS + jboss EAP 6.2 示例

    .Net中如果需要消息队列功能,可以很方便的使用微软自带的MSMQ,对应到Java中,这个功能就是JMS(Java Message Service). 下面以Jboss EAP 6.2环境,介绍一下基 ...

  7. sql 2012 提示列名无效 但可以执行问题

    笔者目前使用Ctrl+Shift+R可以解决这个问题,因为智能感知的问题,需要重新整理一下intellisense.有其他方法,请园友共享一下,谢谢. VS2012及13都有用到智能感知,而在sql里 ...

  8. 翻译qmake文档 目录

    利用空闲时间把qmke的文档翻译出来,翻译水平有限,有些地方翻译的不好,请谅解, 如果您能指出来,我会很感激并在第一时候做出修改. 翻译qmake文档(一) qmake指南和概述 翻译qmake文档( ...

  9. grootJsAPI文档

    groot.view(name,factory) 用于创建一个modelView对象与指令gt-view对应 参数 用途 name 创建的modelView的名称,用groot.vms[name]可以 ...

  10. O2O营销模式(Online To Offline)

    什么是O2O营销模式 O2O营销模式又称离线商务模式,是指线上营销线上购买带动线下经营和线下消费.O2O通过打折.提供信息.服务预订等方式,把线下商店的消息推送给互联网用户,从而将他们转换为自己的线下 ...