分析
那么首先这道题可以用预处理,但是依然是 O ( n 2 ) O(n^2) O(n2),所以我们选择折中的分块,对于在范围内的修改的时候块内修改,输出 O ( 1 ) O(1) O(1),在超过的时候用暴力统计,时间复杂度 O ( n n ) O(n\sqrt n) O(nn)其中暴力询问和单点修改 O ( n ) O(\sqrt n) O(n),但是这道题可以卡块的长度,所以自己算时间复杂度去吧
代码
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#define rr register
using namespace std;
int n,m,bk,a[150001],sum[61][61];
inline signed iut(){
rr int ans=0,f=1; rr char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans*f;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
signed main(){
n=iut(); m=iut(); bk=pow(1.0*n,1.0/3);
for (rr int i=1;i<=n;++i){
a[i]=iut();
for (rr int j=1;j<=bk;++j)
sum[j][i%j]+=a[i];
}
for (rr int i=1;i<=m;++i){
rr char q=getchar();
while (q!='A'&&q!='C') q=getchar();
rr int x=iut(),y=iut();
if (q=='C'){
for (rr int j=1;j<=bk;++j)
sum[j][x%j]+=y-a[x];
a[x]=y;
}
else if (x<bk) print(sum[x][y%x]),putchar(10);
else{
rr int ans=0;
for (rr int i=y;i<=n;i+=x) ans+=a[i];
print(ans); putchar(10);
}
}
return 0;
}