Loj 6280 数列分块入门 4

链接:https://loj.ac/problem/6280

思路:

多设置一个数组sum去存区间值的和就好了,因为数据范围比较大,需要开long long .

实现代码;

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll M = 1e5+10;
ll sum[M],a[M],tag[M],bl[M],n,block;

void update(ll l,ll r,ll c){
    for(ll i = l;i <= min(bl[l]*block,r);i ++)
        a[i] += c,sum[bl[l]]+=c;
    if(bl[l] != bl[r]){
        for(ll i = (bl[r]-1)*block+1;i <= r;i ++)
            a[i] += c,sum[bl[r]]+=c;
    }
    for(ll i = bl[l]+1;i <= bl[r] -1;i ++)
        tag[i] += c;
}

ll query(ll l,ll r){
    ll ret = 0;
    for(ll i = l;i <= min(bl[l]*block,r);i ++)
        ret += a[i]+tag[bl[l]];
    if(bl[l] != bl[r]){
        for(ll i = (bl[r]-1)*block+1;i <= r;i ++)
            ret += a[i] + tag[bl[r]];
    }
    for(ll i = bl[l]+1;i <= bl[r]-1;i ++)
        ret += sum[i]+tag[i]*block;
    return ret;
}

int main()
{
    ll f,l,r,c;
    cin>>n;
    block = sqrt(n);
    for(ll i = 1;i <= n;i ++) cin>>a[i];
    for(ll i = 1;i <= n;i ++){
        bl[i] = (i-1)/block+1;
        sum[bl[i]]+=a[i];
    }
    for(ll i = 1;i <= n;i ++){
        cin>>f>>l>>r>>c;
        if(f == 0) update(l,r,c);
        else cout<<(query(l,r)%(c+1))<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/kls123/p/9135147.html

时间: 2024-11-09 20:24:44

Loj 6280 数列分块入门 4的相关文章

loj 6277 6280 数列分块入门 1 4

参考:「分块」数列分块入门1 – 9 by hzwer 1 Description 给出一个长为\(n\)的数列,以及\(n\)个操作,操作涉及区间加法,单点查值. 思路 用\(tag\)记录每个块整体的增量. Code #include <bits/stdc++.h> #define maxn 50010 #define F(i, a, b) for (int i = (a); i < (b); ++i) #define F2(i, a, b) for (int i = (a); i

LOJ#6284. 数列分块入门 8

#6284. 数列分块入门 8 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计讨论 1 测试数据 题目描述 给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及区间询问等于一个数 ccc 的元素,并将这个区间的所有元素改为 ccc. 输入格式 第一行输入一个数字 nnn. 第二行输入 nnn 个数字,第 i 个数字为 aia_ia?i??,以空格隔开. 接下来输入 nnn 行询问,每行输入三个数字 ll

Loj 6279. 数列分块入门 3

题目描述 给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及区间加法,询问区间内小于某个值 xxx 的前驱(比其小的最大元素). 输入格式 第一行输入一个数字 nnn. 第二行输入 nnn 个数字,第 iii 个数字为 aia_iai?,以空格隔开. 接下来输入 nnn 行询问,每行输入四个数字 opt\mathrm{opt}opt.lll.rrr.ccc,以空格隔开. 若 opt=0\mathrm{opt} = 0opt=0,表示将位于 [l,r][l, r][l,r] 的之间的数字

Loj 6277 数列分块入门 1

题目链接:https://loj.ac/problem/6277 题面: 题目描述 给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及区间加法,单点查值. 输入格式 第一行输入一个数字 nnn. 第二行输入 nnn 个数字,第 iii 个数字为 aia_ia?i??,以空格隔开. 接下来输入 nnn 行询问,每行输入四个数字 opt\mathrm{opt}opt.lll.rrr.ccc,以空格隔开. 若 opt=0\mathrm{opt} = 0opt=0,表示将位于 [l,r][l,

loj#6285 数列分块入门 9 ( 回 滚 )

题目 :  链接 :https://loj.ac/problem/6285 题意:给出一个长为 n的数列,以及 n个操作,操作涉及询问区间的最小众数. 思路:虽然这不是一道 回滚莫队题,就是 暴力分块 的题, 但是 还是 可以用回滚莫队 写滴,好像大部分题解都是 暴力分块. #include<bits/stdc++.h> #define LL long long #define ULL unsigned long long #define rep(i,j,k) for(int i=j;i<

LOJ#6278. 数列分块入门 2

内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计讨论测试数据 题目描述 给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及区间加法,询问区间内小于某个值 xxx 的元素个数. 输入格式 第一行输入一个数字 nnn. 第二行输入 nnn 个数字,第 i 个数字为 aia_ia?i??,以空格隔开. 接下来输入 nnn 行询问,每行输入四个数字 opt\mathrm{opt}opt.lll.rrr.ccc,

#6280. 数列分块入门 4 #6281. 数列分块入门 5

题目描述 给出一个长为 n 的数列,以及 n 个操作,操作涉及区间加法,区间求和. 输入格式 第一行输入一个数字 n. 第二行输入 n 个数字,第 i 个数字为 ai?,以空格隔开. 接下来输入 n 行询问,每行输入四个数字 opt.l.r.c,以空格隔开. 若 opt=0,表示将位于 [l,r]的之间的数字都加 c. 若 opt=1,表示询问位于 [l,r]的所有数字的和 ?mod(c+1). 输出格式 对于每次询问,输出一行一个数字表示答案. 样例 样例输入 4 1 2 2 3 0 1 3

LOJ#6281. 数列分块入门 5

内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计讨论 1 测试数据 题目描述 给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及区间开方,区间求和. 输入格式 第一行输入一个数字 nnn. 第二行输入 nnn 个数字,第 i 个数字为 aia_ia?i??,以空格隔开. 接下来输入 nnn 行询问,每行输入四个数字 opt\mathrm{opt}opt.lll.rrr.ccc,以空格隔开. 若 opt=

LOJ#6282. 数列分块入门 6

内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计讨论测试数据 题目描述 给出一个长为 nnn 的数列,以及 nnn 个操作,操作涉及单点插入,单点询问,数据随机生成. 输入格式 第一行输入一个数字 nnn. 第二行输入 nnn 个数字,第 i 个数字为 aia_ia?i??,以空格隔开. 接下来输入 nnn 行询问,每行输入四个数字 opt\mathrm{opt}opt.lll.rrr.ccc,以空格隔开. 若