整理的算法模板合集: ACM模板
题解by hzwer
区间修改实际上就分情况暴力枚举修改即可。单点查询直接输出,因为我们就是直接维护的一个数组。
#pragma GCC optimize("Ofast")
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<bitset>
#include<map>
#define debug(x) cout << x << "ok" << endl
typedef long long ll;
#define file freopen("1.in", "r", stdin);freopen("1.out", "w", stdout);
const int N = 5e4 + 7, M = 1e5 + 7, INF = 0x3f3f3f3f;
const int B = 260, B2 = 300;
using namespace std;
ll read()
{
ll 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 * 10 + ch - '0';ch = getchar();}
return x * f;
}
int n, m, block;
int val[N];
int bi[N];//block_id
int atage[N];
//l,r是实际的点的编号
void modify(int l, int r, int k)
{
for(int i = l; i <= min(bi[l] * block, r); ++ i)
val[i] += k;
//update(bi[l]);//这里不需要块内有序
if(bi[l] != bi[r]){
//!注意这里是(bi[r] - 1),表示的是上一个 “块”而不是实际节点r
for(int i = ((bi[r] - 1) * block + 1); i <= r; ++ i)
val[i] += k;
//update(bi[r]);
}
//块的编号
for(int i = bi[l] + 1; i <= bi[r] - 1; ++ i)
atage[i] += k;
}
int main()
{
n =read();
block = sqrt(n);
for(int i = 1; i <= n; ++ i)
val[i] = read();
for(int i = 1; i <= n; ++ i)
bi[i] = (i - 1) / block + 1;//1~block是第一块,block + 1 ~ 2 * block是第二块
for(int i = 1; i <= n; ++ i){
int op = read(), a = read(), b = read(), c = read();
if(op == 0)modify(a, b, c);
if(op == 1)printf("%d\n", val[b] + atage[bi[b]]);
}
return 0;
}