分块练习C. interval
分块练习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的更多相关文章
- P3203 [HNOI2010]弹飞绵羊  ——  懒标记?分块?LCT?...FAQ  orz
		
好久没写博客了哈,今天来水一篇._(:з」∠)_ 题目 :弹飞绵羊(一道省选题) 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏 ...
 - P3203 [HNOI2010]弹飞绵羊  ——  懒标记?分块?
		
好久没写博客了哈,今天来水一篇._(:з」∠)_ 题目 :弹飞绵羊(一道省选题) 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏 ...
 - POJ 3468 A Simple Problem with Integers(分块入门)
		
题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS Memory Limit ...
 - HDU 4391 Paint The Wall(分块+延迟标记)
		
Paint The Wall Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
 - 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 ...
 - PHP搭建大文件切割分块上传功能
		
背景 在网站开发中,文件上传是很常见的一个功能.相信很多人都会遇到这种情况,想传一个文件上去,然后网页提示"该文件过大".因为一般情况下,我们都需要对上传的文件大小做限制,防止出现 ...
 - 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 * ...
 - POJ2104 K-th Number [分块做法]
		
传送:主席树做法http://www.cnblogs.com/candy99/p/6160704.html 做那倒带修改的主席树时就发现分块可以做,然后就试了试 思想和教主的魔法差不多,只不过那个是求 ...
 - [LeetCode] Find Right Interval 找右区间
		
Given a set of intervals, for each of the interval i, check if there exists an interval j whose star ...
 
随机推荐
- Redis的持久化之RDB
			
1.什么是Redis的持久化 Redis是一种高级key-value数据库,是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库,所以Redis的所有数据都 ...
 - laravel  上线部署最佳实践
			
nginx 配置 listen 80 default_server; server_name xxxx; index index.php index.html; 优先 index.php ro ...
 - 页面上怎么使用svg
			
svg标签直接在页面使用 不多说. 其他标签使用svg 除了直接使用svg标签,还有如下方法: <object data="your.svg" type="imag ...
 - Java 添加、删除、替换、格式化Word中的文本(基于Spire.Cloud.SDK for Java)
			
Spire.Cloud.SDK for Java提供了TextRangesApi接口可通过addTextRange()添加文本.deleteTextRange()删除文本.updateTextRang ...
 - 算数组的长度cpp
			
今天被自己整傻了.... cpp int 型的数组就别想用strlen来求长度了,会报错的. (当然java 里直接用length就可以了...) 所以我建议用vector!!!!!!
 - PHP xml_error_string() 函数
			
定义和用法 xml_error_string() 函数获取 XML 解析器的错误描述.高佣联盟 www.cgewang.com 如果成功,该函数则返回错误描述.如果失败,则返回 FALSE. 语法 x ...
 - PDOStatement::getColumnMeta
			
PDOStatement::getColumnMeta — 返回结果集中一列的元数据(PHP 5 >= 5.1.0, PECL pdo >= 0.2.0)高佣联盟 www.cgewang. ...
 - Prism.Interactivity 和 Prism.Modularity 介绍
			
Prism.Interactivity: 主要用来截取View即界面的一些处理,而这些功能通过vm 不好实现,只能用 CommandBehaviorBase 来截取处理,特别是在处理界面异常很有用. ...
 - Phantomjs实现后端生成图片文件
			
目录 PhantomJS简介 了解rasterize.js 使用方法 今天,给大家分享一个Java后端利用Phantomjs实现生成图片的功能,同学们使用的时候,可以参考下! PhantomJS简介 ...
 - Python爬取网站上面的数据很简单,但是如何爬取APP上面的数据呢