分块练习C. interval

题目描述

\(N\)个数\(a_i\),\(m\)个操作

\(1\). 从第一个数开始,每隔\(k_i\)个的位置上的数增加\(x_i\)

\(2\). 查询\(l\)到\(r\)的区间和

输入格式

第一行两个整数\(n\),\(m\)

第二行\(n\)个数,\(a_i\)

接下来\(m\)行,每行三个整数,\(a\),\(b\),\(c\)

如果\(a=1\),表示修改操作

否则表示查询 \(b\)到\(c\)的区间和

输出格式

依次输出每个查询

样例

样例输入

10 6

5 1 4 2 3 6 4 1 2 3

1 2 4

2 6 8

1 1 4

2 3 6

1 5 4

2 2 9

样例输出

15

27

51

数据范围与提示

数据均随机生成,保证合法

对于\(50\%\)的数据 \(n,m<=10000\)

对于\(100\%\)的数据,\(n,m<=100000\)

分析

由于数据水到一定境界,所以暴力即可通过本题

但是,怀着务实求真的心态,我们还是要探究一下本题的分块解法

分块的核心是大段维护,局部朴素

因此我们考虑怎么对一个大段整体打上标记

题目中的修改操作是每间隔固定的长度加上一个值

因此我们可以对每一个块开一个\(vector\)记录每次修改时该块内被改动的第一个元素,改动的间隔以及增加的价值

对于间隔小于 $ \sqrt{n} $的修改,我们用上面的方式去打标记

对于间隔大于 $\sqrt{n} $的修改,我们暴力去维护会更优

查询时,我们将区间两端的散点,暴力去加,同时把标记下放

对于中间的大区间,我们直接维护一个\(sum\)加上即可

代码

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
const int maxn = 1e5 + 5;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
int n, m, shuyu[maxn], blo, sum[maxn], a[maxn];
struct asd {
int wz, ad, jz;
asd() {}
asd(int aa, int bb, int cc) { wz = aa, ad = bb, jz = cc; }
};
std::vector<asd> g[maxn];
void xg(int jg, int val) {
if (jg >= blo) {
for (int i = 1; i <= n; i += jg) {
a[i] += val;
sum[shuyu[i]] += val;
}
} else {
int beg = 1;
for (int i = 1; i <= shuyu[n]; i++) {
if (shuyu[beg] == i && beg <= n)
g[i].push_back(asd(beg, jg, val));
int ed = std::min(i * blo, n);
int cz = (ed - beg) / jg;
sum[i] += (cz + 1) * val;
beg += (cz + 1) * jg;
}
}
}
void qk(int id) {
for (int i = 0; i < g[id].size(); i++) {
int beg = g[id][i].wz, jg = g[id][i].ad, val = g[id][i].jz;
for (int j = beg; j <= id * blo; j += jg) {
a[j] += val;
}
}
g[id].clear();
}
int cx(int l, int r) {
int ans = 0;
qk(shuyu[l]);
for (int i = l; i <= std::min(r, shuyu[l] * blo); i++) {
ans += a[i];
}
if (shuyu[l] == shuyu[r])
return ans;
qk(shuyu[r]);
for (int i = r; i >= (shuyu[r] - 1) * blo + 1; i--) {
ans += a[i];
}
for (int i = shuyu[l] + 1; i <= shuyu[r] - 1; i++) {
ans += sum[i];
}
return ans;
}
int main() {
n = read(), m = read();
blo = sqrt(n);
for (int i = 1; i <= n; i++) {
a[i] = read();
shuyu[i] = (i - 1) / blo + 1;
sum[shuyu[i]] += a[i];
}
for (int i = 1; i <= m; i++) {
int aa, bb, cc;
aa = read(), bb = read(), cc = read();
if (aa == 1) {
bb++;
xg(bb, cc);
} else {
printf("%d\n", cx(bb, cc));
}
}
return 0;
}

分块练习C. interval的更多相关文章

  1. P3203 [HNOI2010]弹飞绵羊 —— 懒标记?分块?LCT?...FAQ orz

    好久没写博客了哈,今天来水一篇._(:з」∠)_ 题目 :弹飞绵羊(一道省选题) 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏 ...

  2. P3203 [HNOI2010]弹飞绵羊 —— 懒标记?分块?

    好久没写博客了哈,今天来水一篇._(:з」∠)_ 题目 :弹飞绵羊(一道省选题) 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏 ...

  3. POJ 3468 A Simple Problem with Integers(分块入门)

    题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS   Memory Limit ...

  4. HDU 4391 Paint The Wall(分块+延迟标记)

    Paint The Wall Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  5. POJ 3468 A Simple Problem with Integers (分块)

    Description You have \(N\) integers, \(A_1, A_2, ... , A_N\). You need to deal with two kinds of ope ...

  6. PHP搭建大文件切割分块上传功能

    背景 在网站开发中,文件上传是很常见的一个功能.相信很多人都会遇到这种情况,想传一个文件上去,然后网页提示"该文件过大".因为一般情况下,我们都需要对上传的文件大小做限制,防止出现 ...

  7. Failure to find xxx in xxx was cached in the local repository, resolution will not be reattempted until the update interval of nexus has elapsed or updates are forced @ xxx

    问题: 在linux服务器上使用maven编译war时报错: 16:41:35 [FATAL] Non-resolvable parent POM for ***: Failure to find * ...

  8. POJ2104 K-th Number [分块做法]

    传送:主席树做法http://www.cnblogs.com/candy99/p/6160704.html 做那倒带修改的主席树时就发现分块可以做,然后就试了试 思想和教主的魔法差不多,只不过那个是求 ...

  9. [LeetCode] Find Right Interval 找右区间

    Given a set of intervals, for each of the interval i, check if there exists an interval j whose star ...

随机推荐

  1. 关系数据可视化gephi

    表示对象之间的关系,可通过gephi软件实现,软件下载官方地址https://gephi.org/users/download/ 如何来表示两个对象之间的关系? 把对象变成点,点的大小.颜色可以是它的 ...

  2. 一个简单的Android小实例分享,包含recycleView与recyclerView嵌套

    先上图: 1.首页 2.第二页 3.第三页 项目目录: 代码不多,本人太懒,就不贴了 项目地址:

  3. 《Python Web开发实战》|百度网盘免费下载|Python Web开发

    <Python Web开发实战>|百度网盘免费下载|Python Web开发 提取码:rnz4 内容简介 这本书涵盖了Web开发的方方面面,可以分为如下部分: 1. 使用最新的Flask ...

  4. 「从零单排canal 06」 instance模块源码解析

    基于1.1.5-alpha版本,具体源码笔记可以参考我的github:https://github.com/saigu/JavaKnowledgeGraph/tree/master/code_read ...

  5. Servlet学习之Tomcat控制台中文乱码问题

    Tomcat控制台中文乱码问题 在更新了IDEA2020.1版本后,可以安装官方的简体中文插件,方便我们日常使用,但是更新后再运行Tomcat时,控制台的输出日志出现中文乱码问题,接下来告诉大家如何修 ...

  6. Mac Sourcetree克隆项目提示无效的url

    之前用SoucreTree拉去过另一个账号的git项目,今天创建了一个新的码云账号,克隆里面的项目是一直报错误 > 错误如下: > 原因以及解决方案:

  7. Django学习路5_更新和删除数据库表中元素

    查找所有的元素 Student.objects.all() 查找单个元素 Student.objects.get(主键=值) 主键 pk = xxx 更新数据库数据后进行保存 stu.save() 删 ...

  8. PHP array_walk_recursive() 函数

    实例 对数组中的每个元素应用用户自定义函数: <?phpfunction myfunction($value,$key){echo "The key $key has the valu ...

  9. PHP frenchtojd() 函数

    ------------恢复内容开始------------ 实例 把法国共和历法的日期转换为儒略日计数,然后再转换回法国共和历法的日期: <?php$jd=frenchtojd(3,3,14) ...

  10. PHP connection_aborted() 函数

    实例 创建一个函数(check_abort()),在客户机终止脚本时写入一条日志消息: <?phpfunction check_abort(){if (connection_aborted()) ...