链接:
题意:
给出一个长为 的数列,以及 个操作,操作涉及区间加法,单点查值。
思路:
线段树可以解决,用来学习分块.
分块概念就是,将序列分为sqrt(n)块,每次区间操作在满足一个快时操作块,最多sqrt(n)块, 处于边界时,直接对边界暴力操作,复杂度最多sqrt(n).
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
//#include <memory.h>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <stack>
#include <string>
#include <assert.h>
#include <iomanip>
#define MINF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int MAXN = 5e4+10;
int a[MAXN], Tag[MAXN];
int Rank[MAXN];
int n, part;
void Update(int l, int r, int c)
{
for (int i = l;i <= min(r, Rank[l]*part);i++)
a[i] += c;
if (Rank[l] != Rank[r])
{
for (int i = (Rank[r]-1)*part+1;i <= r;i++)
a[i] += c;
}
for (int i = Rank[l]+1;i <= Rank[r]-1;i++)
Tag[i] += c;
}
int main()
{
scanf("%d", &n);
part = sqrt(n);
for (int i = 1;i <= n;i++)
scanf("%d", &a[i]);
for (int i = 1;i <= n;i++)
Rank[i] = (i-1)/part+1;
int op, l, r, c;
for (int i = 1;i <= n;i++)
{
scanf("%d %d %d %d", &op, &l, &r, &c);
if (op == 0)
Update(l, r, c);
else
printf("%d
", a[r]+Tag[Rank[r]]);
}
return 0;
}