cdq分治解决区间问题
如题,已知一个数列,你需要进行下面两种操作:
1.将某一个数加上x
2.求出某区间每一个数的和
输入输出格式
输入格式:
第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。
第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。
接下来M行每行包含3个整数,表示一个操作,具体如下:
操作1: 格式:1 x k 含义:将第x个数加上k
操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和
输出格式:
输出包含若干行整数,即为所有操作2的结果。
输入输出样例
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=8,M<=10
对于70%的数据:N<=10000,M<=10000
对于100%的数据:N<=500000,M<=500000
样例说明:
故输出结果14、16
然而这个代码T了QAQ
#include<cstdio>
#include<algorithm>
const int maxn = ;
inline int read() {
int x=,f=;char c=getchar();
while(c<''||c>'') {
if(c=='-')f=-;c=getchar();
}
while(c<=''&&c>='') {
x=x*+c-'',c=getchar();
}
return x*f;
}
int n,m,tot,t,ans[maxn];
struct node{
int x,key,id,kind,bl;
bool operator < (const node&a)const {
if(x!=a.x) return x<a.x;
else return kind<a.kind;
}
}q[maxn],tmp[maxn];
void cdq(int l,int r) {
if(l==r) return;
int sum=;
int mid=l+r>>,ll=l,rr=mid+;
for(int i=l;i<=r;i++) {
if(q[i].kind==&&q[i].id<=mid) sum+=q[i].key;
else if(q[i].kind==&&q[i].id>mid) ans[q[i].bl]+=q[i].key*sum;
}
for(int i=l;i<=r;i++) {
if(q[i].id<=mid)tmp[ll++]=q[i];
else tmp[rr++]=q[i];
}
for(int i=l;i<=r;i++) q[i]=tmp[i];
cdq(l,mid);cdq(mid+,r);
}
int main()
{
n=read(),m=read();
for(int x,i=;i<=n;i++) {
x=read();
q[++tot].x=i;q[tot].key=x;q[tot].id=tot;q[tot].kind=;
}
for(int x,y,z;m;m--) {
scanf("%d%d%d",&x,&y,&z);
if(x&) {
q[++tot].x=y;q[tot].key=z;q[tot].id=tot;q[tot].kind=;
}
else {
q[++tot].x=y-;q[tot].key=-;q[tot].id=tot;q[tot].kind=;q[tot].bl=++t;
q[++tot].x=z;q[tot].key=;q[tot].id=tot;q[tot].kind=;q[tot].bl=t;//id : kth operator ,x:the location of the op ;bl : the group of the query sum
}
}
std::sort(q+,q+tot+);
cdq(,tot);
for(int i=;i<=t;i++)
printf("%d\n",ans[i]);
return ;
}
cdq分治解决区间问题的更多相关文章
- [用CDQ分治解决区间加&区间求和]【习作】
[前言] 作为一个什么数据结构都不会只会CDQ分治和分块的蒟蒻,面对区间加&区间求和这么难的问题,怎么可能会写线段树呢 于是,用CDQ分治解决区间加&区间求和这篇习作应运而生 [Par ...
- cdq分治解决三维偏序
问题背景 在三维坐标系中有n个点,坐标为(xi,yi,zi). 定义一个点A比一个点B小,当且仅当xA<=xB,yA<=yB,zA<=zB.问对于每个点,有多少个点比它小.(n< ...
- CDQ 分治解决和点对有关的问题
具体可以去这篇博客学习: https://oi-wiki.org/misc/cdq-divide/
- 【教程】简易CDQ分治教程&学习笔记
前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦! CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...
- [学习笔记]CDQ分治和整体二分
序言 \(CDQ\) 分治和整体二分都是基于分治的思想,把复杂的问题拆分成许多可以简单求的解子问题.但是这两种算法必须离线处理,不能解决一些强制在线的题目.不过如果题目允许离线的话,这两种算法能把在线 ...
- bzoj-1492 货币兑换Cash (2)——CDQ分治
题意: 略 见上一篇 题解: 方程还是那个方程f[i]=A[i] * X[j] + B[i] * Y[j]. 化简为Y[i]=(-A[i]/B[i]) * X[i] + f[i]/B[i]这一坨: 既 ...
- 【BZOJ4237】 稻草人 CDQ分治+单调栈
## 题目描述 JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下 ...
- BZOJ4237稻草人——单调栈+CDQ分治
题目描述 JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要满足以下条件: ...
- CDQ 分治
引言: 什么是CDQ分治?其实这是一种思想而不是具体算法,因此CDQ分治覆盖的范围相当广泛,在 OI 界初见于陈丹琦 2008 年的集训队作业中,故被称为CDQ分治. 大致分为三类: cdq分治解决与 ...
随机推荐
- linux学习(四) -- supervisor守护进程
supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启. 1.安装 apt-get install ...
- Python框架之Django学习笔记(十二)
Django站点管理 十一转眼结束,说好的充电没能顺利开展,反而悠闲的看了电视剧以及去影院看了新上映的<心花路放>.<亲爱的>以及<黄金时代>,说好的劳逸结合现在回 ...
- Feign请求报请求超时
Feign的底层基于Rabbion实现的,一般情况下直接导入feign的依赖,然后调用feignClient去发送请求,报请求超时. application.yml #hystrix的超时时间 hys ...
- Jquery鼠标悬停按钮图标动态变化效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 使用CoreLocation进行定位(Swift版)
在应用开发中,很多情况需要我们获取到当前的位置和高度信息,方便搜索周边,查看周边相同应用等,一切与定位有关的都得使用CoreLocation库,而且,系统是不允许第三发定位的,当然可以使用第三方对其封 ...
- [HDU3516] Tree Construction [四边形不等式dp]
题面: 传送门 思路: 这道题有个结论: 把两棵树$\left[i,k\right]$以及$\left[k+1,j\right]$连接起来的最小花费是$x\left[k+1\right]-x\left ...
- cf 853 B Jury Meeting [前缀和]
题面: 传送门 思路: 看完题目以后,首先有一个结论:每个人都是先去到首都,等待开会,开会结束以后再一个个走掉 而且这道题只有去首都和离开首都的机场 因此考虑计算去首都的飞机的前缀最小花费,以及离开首 ...
- BZOJ1801 [Ahoi2009]chess 中国象棋 【dp】
题目 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放置方法,中国像棋中炮的行走方式大家应该很清楚吧. 输入格式 一行包含两个整数N,M,中间用空格分开. ...
- Codeforces Round #363 (Div. 2) B 暴力
Description You are given a description of a depot. It is a rectangular checkered field of n × m siz ...
- 洛谷 P1270 “访问”美术馆
P1270 “访问”美术馆 题目描述 经过数月的精心准备,Peer Brelstet,一个出了名的盗画者,准备开始他的下一个行动.艺术馆的结构,每条走廊要么分叉为两条走廊,要么通向一个展览室.Peer ...