当前位置: 首页 > news >正文

数列分块入门4

题目描述

给出一个长为 n n n 的数列,以及 n n n 个操作,操作涉及区间加法,区间求和。

输入格式

第一行输入一个数字 n n n

第二行输入 n n n 个数字,第 i 个数字为 a i a_i ai,以空格隔开。

接下来输入 n n n 行询问,每行输入四个数字 o p t , l , r , c opt,l,r,c opt,l,r,c,以空格隔开。

opt = 0,表示将位于 [ l , r ] [l, r] [l,r] 的之间的数字都加 c c c

opt = 1,表示询问位于 [ l , r ] [l, r] [l,r] 的所有数字的和   m o d   ( c + 1 ) \bmod (c+1) mod(c+1)

输出格式

对于每次询问,输出一行一个数字表示答案。

样例

样例输入1:

4
1 2 2 3
0 1 3 1
1 1 4 4
0 1 2 2
1 1 2 4

样例输出1:

1
4

数据范围

对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 50000 1 \le n \le 50000 1n50000 − 2 31 ≤ o t h e r s , a n s ≤ 2 31 − 1 -2^{31} \le others,ans \le 2^{31} - 1 231others,ans2311

题解

与数列分块1类似,区间加法如果是散块就直接加,整块就在整块上打标记。询问时散块直接枚举,整块将预处理的整块的和加上。

块长建议开 n 0.66 n^{0.66} n0.66,这样会更快。

#include<bits/stdc++.h>
using namespace std;
int n;
long long a[51010];
struct kuai{
    long long kuai_cnt, kuai_len, belong[51010], add[310], b[51010];
    long long kuai[310];
    void init(){
        kuai_len = sqrt(n);
        kuai_cnt = (n + kuai_len - 1) / kuai_len;
        for(int i = 1; i <= kuai_cnt; ++ i){
            for(int j = (i - 1) * kuai_len + 1; j <= i * kuai_len; ++ j){
                kuai[i] += a[j];
                belong[j] = i;
                b[j] = a[j];
            }
        }
    }
    void change(int l, int r, int d){
        if(belong[l] == belong[r]){
            for(int i = l; i <= r; ++ i){
                b[i] += d;
            }
            kuai[belong[l]] += (r - l + 1) * d;
        }
        else{
            for(int i = l; i <= belong[l] * kuai_len; ++ i){
                b[i] += d;
                kuai[belong[l]] += d;
            }
            for(int i = belong[l] + 1; i <= belong[r] - 1; ++ i){
                add[i] += d;
                kuai[i] += d * (min((long long)n, i * kuai_len) - (i - 1) * kuai_len );
            }
            for(int i = (belong[r] - 1) * kuai_len + 1; i <= r; ++ i){
                b[i] += d;
                kuai[belong[r]] += d;
            }
        }
    }
    long long query(int l, int r){
        if(belong[l] == belong[r]){
            long long ans = 0;
            for(int i = l; i <= r; ++ i){
                ans += b[i] + add[belong[l]];
            }
            return ans;
        }
        else{
            long long ans = 0;
            for(int i = l; i <= belong[l] * kuai_len; ++ i){
                ans += b[i] + add[belong[l]];
            }
            for(int i = belong[l] + 1; i <= belong[r] - 1; ++ i){
                ans += kuai[i];
            }
            for(int i = (belong[r] - 1) * kuai_len + 1; i <= r; ++ i){
                ans += b[i] + add[belong[r]];
            }
            return ans;
        }
    }
}k;
int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; ++ i){
        scanf("%d", &a[i]);
    }
    k.init();
    for(int i = 1; i <= n; ++ i){
        int op, l, r, d;
        scanf("%d %d %d %d", &op, &l, &r, &d);
        if(op == 0){
            k.change(l, r, d);
        }
        else{
            printf("%lld\n", k.query(l, r) % (d + 1));
        }
    }
    return 0;
}

相关文章:

  • 信奥赛之c++课后练习题及解析(关系运算符+选择结构)
  • JAVA中正则表达式的入门与使用
  • Matlab 分数阶PID控制永磁同步电机
  • Codeforces Round 1016 (Div. 3) C ~ G 题解
  • Golang|协程
  • python-1. 找单独的数
  • 关于nacos注册的服务的ip异常导致网关路由失败的问题
  • 科技项目验收测试怎么做?验收测试报告如何获取?
  • 网安小白筑基篇六:数据库(增删改语法、表约束、查询语句、多表查询、附phppython小练习)
  • Kubernetes集群环境搭建与初始化
  • 【实战手册】8000w数据迁移实践:MySQL到MongoDB的完整解决方案
  • 蓝桥杯备赛知识点总结
  • 小白学习java第12天(下):IO流之字符输入输出
  • 联影医疗智能体 重构医疗新范式
  • 【物联网】PWM控制蜂鸣器
  • aosp13增加摄像头控制功能实现
  • C#MVC项目引用Swagger的详细步骤
  • C++指针(二)
  • DAOS系统架构-组件
  • Mamba原理及在low-level vision的工作[持续更新]
  • 用dw设计网站怎么做/肥城市区seo关键词排名
  • 西安有哪些网站建设公司/2345网址导航智能主板
  • 360做网站和推广怎么样/网络竞价推广开户
  • 免费设计网站平台/线上广告推广
  • 电子商务网站建设下载/公司网站设计制作
  • 什么网站专做外贸/关键词数据分析工具有哪些