题目大意:
做一个粒子的实验,粒子初始有一定的能量,实验过程中倘若第i个粒子被注入k能量,那该粒子就会增加k能量,同时第2i,3i,4i……(即i的倍数的粒子)也会增加k能量。
有一台特殊的机器,能够为一段连续的粒子注入一定的能量,需要回答相应粒子能量的大小
单点查询的时候爆枚它的约数,那么我们有 O(N) 次区间修改和 O(NN−−√) 次单点查询,使用分块可以使修改做到单词修改 O(N−−√) 查询 O(1) ,总时间代价 O(NN−−√)
#include <bits/stdc++.h>
#define N 300050
#define k 550
using namespace std;
typedef long long LL;
inline int rd() {
int 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,t[N];
LL a[N],b[N],g[N];
int main() {
n = rd();
for (int i=1;i<=n;i++) b[i] = rd();
for (int i=1;i<=n;i++) t[i] = (i-1) / k + 1;
m = rd();
while (m--) {
int cmd = rd();
if (cmd == 1) {
int x = rd(), tp = sqrt(x);
LL ans = b[x];
for (int i=1;i<=tp;i++) if (x%i == 0){
ans += a[i] + g[ t[i] ];
if (i*i != x) ans += a[x/i] + g[ t[x/i] ];
}
printf("%lld\n",ans);
} else {
int l = rd(), r = rd(), d = rd();
if (t[r]-t[l]>2) {
for (int i=l;i<=t[l]*k;i++) a[i] += d;
for (int i=(t[r]-1)*k+1;i<=r;i++) a[i] += d;
for (int i=t[l]+1;i<=t[r]-1;i++) g[i] += d;
} else {
for (int i=l;i<=r;i++) a[i] += d;
}
}
}
return 0;
}