链接:https://ac.nowcoder.com/acm/contest/392/F
来源:牛客网

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

因为上次在月月面前丢人了,所以华华决定开始学信息学。十分钟后,他就开始学树状数组了。这是一道树状数组的入门题:

给定一个长度为N的序列A,所有元素初值为0。接下来有M次操作或询问:
操作:输入格式:1 D K,将ADAD加上K。
询问:输入格式:2 L R,询问区间和,即∑Ri=LAi∑i=LRAi。

华华很快就学会了树状数组并通过了这道题。月月也很喜欢树状数组,于是给华华出了一道进阶题:
给定一个长度为N的序列A,所有元素初值为0。接下来有M次操作或询问:
操作:输入格式:1 D K,对于所有满足1≤i≤N1≤i≤N且i≡0(modD)i≡0(modD)的i,将AiAi加上K。
询问:输入格式:2 L R,询问区间和,即∑Ri=LAi∑i=LRAi。
华华是个newbie,怎么可能会这样的题?不过你应该会吧。

输入描述:

第一行两个正整数N、M表示序列的长度和操作询问的总次数。
接下来M行每行三个正整数,表示一个操作或询问。

输出描述:

对于每个询问,输出一个非负整数表示答案。
示例1

输入

复制

10 6
1 1 1
2 4 6
1 3 2
2 5 7
1 6 10
2 1 10

输出

复制

3
5
26

备注:

1≤N,M≤1051≤N,M≤105,1≤D≤N1≤D≤N,1≤L≤R≤N1≤L≤R≤N,1≤K≤1081≤K≤108

解题思路:首先对于询问区间和我们可以很容易想到需要建立一个树状数组,但是对于更新操作却有点棘手,对于所有满足1≤i≤N且i≡0(modD)的i,将Ai加上K,即需要使下标为D的倍数的数加上a[i],而这些数基本遍布整个区间[1,n],特别是当D很小时,复杂度越高。
但是我们可以发现对于D比较小的情况,这类情况也比较有限。比如当D大于sqrt(n)时,我们所要更新的数字的个数也最多也不超过sqrt(n),而对于这部分数据我们可以直接暴力更新就好了,而当D小于等于sqrt(n),我们可以用一个标记数组lazy[D]累计起来,标记
lazy[D]+=k,这样我们就相当于把区间[1,n]的任意下标x如果x<sqrt(n)把其和其在区间中的倍数看成一个块,当我们查询区间和sum[l,r]时我们便可以用当前区间和(使用树状数组ask(r)-ask(l-1)),加上各个块在该区间的个数(r-l+1)乘以该块的标记值(lazy数组值)。
例如:
n=12
下标: 1 2 3 4 5 6 7 8 9 10 11 12
值: 2 1 7 14 6 4 1 7 10 3 7 9 块数目sqrt(n)=3
把下标为1的倍数看成是一块,即下标为1 2 3 4 5 6 7 8 9 10 11 12的数
把下标为2的倍数也看成是一块,即下标为 2 4 6 8 10 12的这几个数
把下标为3的倍数也看成是一块,即下标为3 6 9 12的这几个数
当D的值大于3时,如D=5,k=1,我们就直接暴力更新各个值更新下标为5的值和下标为10的值变成:
下标: 1   2   3   4   5   6   7   8  9   10  11   12
值:   2   1   7  14   7  4   1   7  10   4   7   9
而当D=2,k=1时,我们选择不更新数组,而是直接用lazy数组标记,使得lazy[2]+=1,它表示的是2的倍数这一整块数都需要加上1
然后当我们询问区间和时,如询问区间[3,10]的和时,我们先用树状数组求数组在该区间的和sum=7+14+7+4+1+7+10+4=54;
然后我们遍历每一个块,看是否含有标记值,如果有,则加上该块的标记值*该块在查询区间内的个人。
在例子中,lazy[1]为0(1的倍数并未被标记),表示无标记,则跳过;
当遍历到2的倍数这一块时,因为lazy[i]=1含有值,所以我们需要使sum+=lazy[2]+(10/2-3/2)(其中10/2-3/2表示区间[3,10]中2的倍数的个数)
而当遍历到3的倍数时,因为lazy[3]=0所以也会跳过,这样我们便得出了结果。 代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6;
int n,m;
ll sum[maxn],lazy[maxn];
int lowbit(int x){return x&(-x);}
void add(int x,ll val){
for(int i=x;i<=n;i+=lowbit(i))
sum[i]+=val;
}
ll ask(int x){
ll res=;
for(int i=x;i;i-=lowbit(i))
res+=sum[i];
return res;
}
int main(){
scanf("%d%d",&n,&m);
int block=sqrt(n);
while(m--){
int id,x,y;
scanf("%d%d%d",&id,&x,&y);
if(id==){
if(x>block)
for(int i=x;i<=n;i+=x)add(i,y); //想较大,暴力更新下标为x的倍数的值
else lazy[x]+=y; //x值较小,用数组标记x的倍数这个块
}
else{
ll ans=ask(y)-ask(x-);
for(int i=;i<=block;i++)
if(lazy[i]) //如果这个块有标记值,加上该标记值
ans+=(y/i-(x-)/i)*lazy[i];
printf("%lld\n",ans);
}
}
return ;
}

牛客小白月赛12 F 华华开始学信息学 (分块+树状数组)的更多相关文章

  1. 牛客小白月赛16 H小阳的贝壳 (线段树+差分数组)

    链接:https://ac.nowcoder.com/acm/contest/949/H来源:牛客网 题目描述 小阳手中一共有 n 个贝壳,每个贝壳都有颜色,且初始第 i 个贝壳的颜色为 colico ...

  2. 牛客小白月赛12 J 月月查华华的手机 (序列自动机模板题)

    链接:https://ac.nowcoder.com/acm/contest/392/J 来源:牛客网 题目描述 月月和华华一起去吃饭了.期间华华有事出去了一会儿,没有带手机.月月出于人类最单纯的好奇 ...

  3. 牛客小白月赛12 H 华华和月月种树

    题目链接: 题意:有三个操作 操作 1:表示节点 i 长出了一个新的儿子节点,权值为0,编号为当前最大编号 +1(也可以理解为,当前是第几个操作 1,新节点的编号就是多少). 操作 2:表示华华上线做 ...

  4. 牛客小白月赛6 F 发电 树状数组单点更新 求区间乘积 模板

    链接:https://www.nowcoder.com/acm/contest/136/F来源:牛客网  HA实验是一个生产.提炼“神力水晶”的秘密军事基地,神力水晶可以让机器的工作效率成倍提升.   ...

  5. 牛客练习赛38 D 题 出题人的手环 (离散化+树状数组求逆序对+前缀和)

    链接:https://ac.nowcoder.com/acm/contest/358/D来源:牛客网 出题人的手环 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他 ...

  6. 牛客小白月赛12 C 华华给月月出题 (积性函数,线性筛)

    链接:https://ac.nowcoder.com/acm/contest/392/C 来源:牛客网 华华给月月出题 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K, ...

  7. 牛客网 牛客小白月赛12 B.华华教月月做数学-A^B mod P-快速幂+快速乘

    链接:https://ac.nowcoder.com/acm/contest/392/B来源:牛客网 华华教月月做数学 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其 ...

  8. 牛客小白月赛12 H 华华和月月种树 (离线dfs序+线段树)

    链接:https://ac.nowcoder.com/acm/contest/392/H 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 131072K,其他语言2621 ...

  9. 牛客小白月赛12 D 月月给华华出题 (欧拉函数,数论,线筛)

    链接:https://ac.nowcoder.com/acm/contest/392/D 来源:牛客网 月月给华华出题 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 131072K, ...

随机推荐

  1. ESLint常见命令(规则表)

    1 禁用 ESLint: /* eslint-disable */ ; console.log(a); /* eslint-enable */ 2 禁用一条规则: /*eslint-disable n ...

  2. flex实现三栏等分布局

    前言 在实际开发中,我们经常会想要实现的一种布局方式就是三栏等分布局,那么我们如何来解决这个问题呢? 解决 方法一:flex 外层容器也就是ul设置display:flex,对项目也就是li设置fle ...

  3. MySQL Connector/ODBC 2.50 (MyODBC 2.50)连接方式

    一.MySQL Connector/ODBC 2.50 (MyODBC 2.50)连接方式 1.本地数据库连接Driver={MySQL};Server=localhost;Option=16834; ...

  4. windows浏览器访问虚拟机开的rabbitmq服务,无法访问

    根据这个博主的建议 https://blog.csdn.net/csdnliuxin123524/article/details/78207427 换了一个浏览器上火狐浏览器输入“localhost: ...

  5. Excel文件读取的两种方式

    1.Pandas库的读取操作 from pandas import read_excel dr=read_excel(filename,header) dr#dataframe数据 dw=DataFr ...

  6. Gevent 性能和 gevent.loop 的运用和带来的思考

    知乎自己在底层造了非常多的轮子,而且也在服务器部署方面和数据获取方面广泛使用 gevent 来提高并发获取数据的能力.现在开始我将结合实际使用与测试慢慢完善自己对 gevent 更全面的使用和扫盲. ...

  7. comparable和comparator

    Comparable Comparable可以认为是一个内部比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,在compareTo方法中指定具体的比较方法. comp ...

  8. Yii的数值比较验证器

    该验证器比对两个特定输入值之间的关系 是否与 operator 属性所指定的相同. compareAttribute:用于与原属性相比对的属性名称. 当该验证器被用于验证某目标属性时, 该属性会默认为 ...

  9. 在Mac 系统上使用MAMP搭建PHP开发环境

    1.下载MAMP套件 下载地址为https://www.mamp.info/en/ 2.安装此.dmg文件 3.配置apache虚拟主机 (1)在/Applications/MAMP/conf/apa ...

  10. Java多线程之单例模式(线程安全)

    package org.study2.javabase.ThreadsDemo.sync; /** * @Auther:GongXingRui * @Date:2018/9/20 * @Descrip ...