for(i=k;i<=n;i+=p)
ans+=value[i];

for(p=1;p<=n;p++) //枚举模数
ans[p][i%p]+=value[i]; //处理对应的贡献

$O(n^2)$

for(p=1;p<=size;p++) //只枚举[1,size]中的
ans[p][i%p]+=value[] //处理对应的贡献

void change(int i,int v) //将value[i]改为v
{
for(p=1;p<=size;p++)
ans[p][i%p]=ans[p][i%p]-value[i]+v; //更新答案
value[i]=v; //更新value数组
}

 1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <algorithm>
5 #include <cmath>
6 using namespace std;
7 const int Maxn=150100;
8 const int Sqrt=2000;
9 int n,m,Block,a[Sqrt][Sqrt],x,y,v[Maxn];
10 int main()
11 {
12     scanf("%d%d",&n,&m); Block=(int)sqrt(n);
13     for (int i=1;i<=n;i++) scanf("%d",&v[i]);
14     memset(a,0,sizeof(a));
15     for (int i=1;i<=Block;i++)
16         for (int j=1;j<=n;j++) a[i][j%i]+=v[j];
17     for (int i=1;i<=m;i++)
18     {
19         char ch=getchar();
20         while (ch!='A' && ch!='C') ch=getchar();
21         scanf("%d%d",&x,&y);
22         if (ch=='A')
23         {
24             if (x<=Block) printf("%d\n",a[x][y]); else
25             {
26                 int Ret=0; for (int i=y;i<=n;i+=x) Ret+=v[i]; printf("%d\n",Ret);
27             }
28         }
29         if (ch=='C')
30         {
31             for (int i=1;i<=Block;i++)
32                 a[i][x%i]=a[i][x%i]-v[x]+y;
33             v[x]=y;
34         }
35     }
36     return 0;
37 }
C++