数列分块入门 1 (单点查值,区间加法)

简介: 数列分块入门 1 (单点查值,区间加法)

描述:


给出一个长为n 的数列,以及 n 个操作,操作涉及区间加法,单点查值。


输入:


第一行输入一个数字n。

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

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

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

若opt=1,表示询问ar 的值(l和c忽略)。


输出:


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

int len=sqrt(n);//块长
int add[N];//每个块要加的元素
block[i] //第 i 个元素所在的块的编号
len*block[i]//第 i 个块的右边界
(block[i]-1)*len+1//第 i 个块的左边界
block[i]=(i-1)/len+1;//元素与块编号对应关系
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const ll maxx = 1e18;
const int N = 1e5+100;
const int p = 1e4;
const double eps = 1e-8;
int n;
int a[N],block[N];
int len;//块长 
int add[N];
void Add(int l,int r,int c)
{   
  for(int i=l;i<=min(r,len*block[l]);i++)
    a[i]+=c;//处理左边非整块
  if(block[l]!=block[r])
    for(int i=(block[r]-1)*len+1;i<=r;i++)
      a[i]+=c;//处理右边非整块
  for(int i=block[l]+1;i<=block[r]-1;i++)
    add[i]+=c;//处理中间的整块 
}
void query(int x)
{
  printf("%d\n",a[x]+add[block[x]]);
}//查询
int opt,l,r,c;
int main()
{
  cin>>n;
  len=sqrt(n);
  for(int i=1;i<=n;i++)
  {
    scanf("%d",&a[i]);
    block[i]=(i-1)/len+1;
  }
  for(int i=1;i<=n;i++)
  {
    cin>>opt>>l>>r>>c;
    if(opt==0) Add(l,r,c);
    else query(r);
  } 
}

目录
相关文章
|
6月前
|
算法 测试技术 C++
【动态规划】【离线查询】【前缀和】689. 三个无重叠子数组的最大和
【动态规划】【离线查询】【前缀和】689. 三个无重叠子数组的最大和
|
6月前
|
算法 测试技术 C#
二分查找:LeetCode2035:将数组分成两个数组并最小化数组和的差
二分查找:LeetCode2035:将数组分成两个数组并最小化数组和的差
|
6月前
|
机器学习/深度学习 算法 测试技术
【动态规划】【子数组划分】【前缀和】1977. 划分数字的方案数
【动态规划】【子数组划分】【前缀和】1977. 划分数字的方案数
|
5月前
【LeetCode刷题】滑动窗口思想解决:最大连续1的个数 III、将x减到0的最小操作数
【LeetCode刷题】滑动窗口思想解决:最大连续1的个数 III、将x减到0的最小操作数
|
6月前
|
算法 测试技术 C++
【动态规划 区间dp 位运算】3117. 划分数组得到最小的值之和
【动态规划 区间dp 位运算】3117. 划分数组得到最小的值之和
【动态规划 区间dp 位运算】3117. 划分数组得到最小的值之和
|
6月前
|
算法 测试技术 C#
【并集查找 最大公约数 调和数】952. 按公因数计算最大组件大小
【并集查找 最大公约数 调和数】952. 按公因数计算最大组件大小
|
6月前
|
算法 测试技术 C#
【线段树 区间位运算模板】3117划分数组得到最小的值之和
【线段树 区间位运算模板】3117划分数组得到最小的值之和
|
6月前
|
人工智能 算法
前缀和算法题(区间次方和、小蓝平衡和、大石头的搬运工、最大数组和)
前缀和算法题(区间次方和、小蓝平衡和、大石头的搬运工、最大数组和)