题目描述

如题,已知一个数列,你需要进行下面两种操作:

1.将某一个数加上x

2.求出某区间每一个数的和

输入输出格式

输入格式:

第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

接下来M行每行包含3个整数,表示一个操作,具体如下:

操作1: 格式:1 x k 含义:将第x个数加上k

操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

输出格式:

输出包含若干行整数,即为所有操作2的结果。

输入输出样例

输入样例#1: 复制

5 5
1 5 4 2 3
1 1 3
2 2 5
1 3 -1
1 4 2
2 1 4
输出样例#1: 复制

14
16

说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=8,M<=10

对于70%的数据:N<=10000,M<=10000

对于100%的数据:N<=500000,M<=500000

样例说明:

故输出结果14、16

CDQ分治维护二维偏序

第一维用排序搞掉

第二维用CDQ分治

慢的要死。。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
using namespace std;
#define ls T[now].ch[0]
#define rs T[now].ch[1]
const int MAXN=*1e6+;
inline char nc()
{
static char buf[MAXN],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,MAXN,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
char c=nc();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=nc();}
while(c>=''&&c<=''){x=x*+c-'',c=nc();}
return x*f;
}
int n,m;
struct node
{
int idx;//第几次询问
int val;//修改的值
int type;//操作类型
bool operator<( const node &a) const {
return idx==a.idx?type<a.type:idx<a.idx;}
}Q[MAXN];
int qidx=;//操作的个数
int aidx=;//询问的个数
int ans[MAXN];
node tmp[MAXN];
void CDQ(int l,int r)
{
if(r-l<=) return ;
int mid=(l+r)>>;CDQ(l,mid);CDQ(mid,r);
int sum=;
int p=l,q=mid,o=;
while(p<mid&&q<r)
{
if(Q[p]<Q[q])
{
if(Q[p].type==) sum+=Q[p].val;
tmp[o++]=Q[p++];
}
else
{
if( Q[q].type==) ans[Q[q].val]-=sum;
else if(Q[q].type==) ans[Q[q].val]+=sum;
tmp[o++]=Q[q++];
}
}
while(p<mid) tmp[o++]=Q[p++];
while(q<r)
{
if( Q[q].type==) ans[Q[q].val]-=sum;
else if(Q[q].type==) ans[Q[q].val]+=sum;
tmp[o++]=Q[q++];
}
for(int i=;i<o;i++) Q[i+l]=tmp[i];
}
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#else
#endif
n=read();m=read();
for(int i=;i<=n;i++)
{
Q[qidx].idx=i;
Q[qidx].type=;
Q[qidx].val=read();++qidx;
}
for(int i=;i<m;i++)
{
int type=read();
Q[qidx].type=type;
if(type==) Q[qidx].idx=read(),Q[qidx].val=read();
else
{
int l=read(),r=read();
Q[qidx].idx=l-;Q[qidx].val=aidx;++qidx;
Q[qidx].type=;Q[qidx].idx=r;Q[qidx].val=aidx;aidx++;
}
++qidx;
}
CDQ(,qidx);
for(int i=;i<aidx;i++) printf("%d\n",ans[i]);
return ;
}

洛谷P3374 【模板】树状数组 1(CDQ分治)的更多相关文章

  1. 洛谷.3374.[模板]树状数组1(CDQ分治)

    题目链接 简易CDQ分治教程 //每个操作分解为一个有序数对(t,p),即(时间,操作位置),时间默认有序,用CDQ分治处理第二维 //对于位置相同的操作 修改优先于查询 //时间是默认有序的 所以可 ...

  2. 洛谷 P3688 - [ZJOI2017]树状数组(二维线段树+标记永久化)

    题面传送门 首先学过树状数组的应该都知道,将树状数组方向写反等价于前缀和 \(\to\) 后缀和,因此题目中伪代码的区间求和实质上是 \(sum[l-1...n]-sum[r...n]=sum[l-1 ...

  3. 【 HDU - 4456 】Crowd (二维树状数组、cdq分治)

    BUPT2017 wintertraining(15) #5A HDU 4456 题意 给你一个n行n列的格子,一开始每个格子值都是0.有M个操作,p=1为第一种操作,给格子(x,y)增加z.p=2为 ...

  4. ●洛谷P3688 [ZJOI2017]树状数组

    题链: https://www.luogu.org/problemnew/show/P3688题解: 二维线段树. 先不看询问时l=1的特殊情况. 对于一个询问(l,r),如果要让错误的程序得到正确答 ...

  5. LUGOU P3374 【模板】树状数组 1(CDQ 分治)

    传送门 拿个二维偏序练练cdq板子,其实就和归并排序差不多,复杂度不太会,似乎nlogn?. #include<iostream> #include<cstdio> #incl ...

  6. [模板] 树状数组 (C++ class)

    闲来无事(其实是打了两三道树状数组题),写了个树状数组模板…… /* Author: hotwords */ template<typename tp> class BinTree { p ...

  7. HDU 1166 线段树模板&树状数组模板

    HDU1166 上好的线段树模板&&树状数组模板 自己写的第一棵线段树&第一棵树状数组 莫名的兴奋 线段树: #include <cstdio> using nam ...

  8. 【洛谷 p3374】模板-树状数组 1(数据结构)

    题目:已知一个数列,你需要进行下面两种操作:1.将某一个数加上x:2.求出某区间每一个数的和. 解法:树状数组求前缀和. #include<cstdio> #include<cstd ...

  9. 【洛谷 p3368】模板-树状数组 2(数据结构)

    题目:已知一个数列,你需要进行下面两种操作:1.将某区间每一个数数加上x:2.求出某一个数的和. 解法:树状数组+前缀和优化.数组中每位存和前一位的数的差,这样区间修改只用改两位,单点询问就是求前缀和 ...

  10. POJ2299逆序对模板(树状数组)

    题目:http://poj.org/problem?id=2299 只能相邻两个交换,所以交换一次只会减少一个逆序对.所以交换次数就是逆序对数. ps:原来树状数组还可以记录后边lowbit位的部分和 ...

随机推荐

  1. 【C#】C#托付和事件的实例解说

    using System; namespace delegate_event { // 定义一个猫类 class Cat { // 定义一个名字字段 private string name; // 创 ...

  2. 翻翻git之---炫酷的自己定义翻滚View TagCloudView

    转载请注明出处:王亟亟的大牛之路 周一好,又到了每周最困的一天.近期都被啮齿类动物搞的累死,废话不多,今天上一个自己定义的ViewGroup实现一个3D球形集合. 效果图: 效果还不错,能够作为短小文 ...

  3. HIT 2255 Not Fibonacci(矩阵高速幂)

    #include <iostream> #include <cstdio> #include <cstring> using namespace std; cons ...

  4. 在VPS上用Outline Manager 建立*** 增强版服务器

    在VPS上用Outline Manager 建立*** 增强版服务器 原文 https://free.com.tw/google-outline/ Outline 是Google Jigsaw的一款开 ...

  5. 用 shell 获取本机的网卡名称

    用 shell 获取本机的网卡名称 # 用 shell 获取本机的网卡名称 ls /sys/class/net # 或者 ifconfig | grep "Link" | awk ...

  6. vue25---vue2.0变化

    组件模版: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  7. 如何搭建Eclipse +Apache Tomcat配置Java开发环境

    Linux平台下如何搭建Eclipse +Apache Tomcat配置的Java开发环境 本文出自 "李晨光原创技术博客" 博客,请务必保留此出处http://chenguang ...

  8. linux下chm阅读器

    推荐使用Okular这个软件,Okular是一个pdf阅读器,但是对chm文件支持很好.

  9. javaScript [[scope]]学习笔记

    在javaScript 学习中,闭包肯定是一个让人头疼的问题,而闭包必定离不开[[scope]]作用域 scope存储了执行期上下文的集合 而了解scope以及scope链又是一个十分抽象的问题 我们 ...

  10. BZOJ1367: [Baltic2004]sequence(左偏树)

    Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sample Output 13 解题思路: 有趣的数学题. 首先确定序 ...