题目描述:
qwqqq
题目分析:
暴力如何求解呢?
for(int i=k;i<=n;i+=p)
ans+=val[i];
考虑预处理
ans[i][j]表示模数为i时内存池j的和
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
ans[j][i%j]+=val[i];
这样处理是
O(N2)
O
(
N
2
)
考虑到当p特别大时,暴力循环求解不会太慢,我们就只预处理模数到
(√n)
(
n
)
for(int i=1;i<=n;i++)
for(int j=1;j<=siz;j++)
ans[j][i%j]+=val[i];
当模数<=siz时,直接O(1)求解,反之暴力求解
修改时进行暴力修改即可
复杂度为
O(n−−√∗(n+m))
O
(
n
∗
(
n
+
m
)
)
题目链接:
Ac 代码:
#include <cstdio>
#include <iostream>
#include <cmath>
int ans[151000][400];
int val[151000];
int n,m;
int main()
{
scanf("%d%d",&n,&m);
int siz=std::sqrt(n);
for(int i=1;i<=n;i++)
scanf("%d",&val[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=siz;j++)
ans[j][i%j]+=val[i];
for(int i=1;i<=m;i++)
{
char s[10];
int p,k;
scanf("%s",s);
scanf("%d%d",&p,&k);
if(s[0]=='A')
{
if(p<=siz) printf("%d\n",ans[p][k]);
else
{
int res=0;
for(int j=k;j<=n;j+=p)
res+=val[j];
printf("%d\n",res);
}
}
else
{
for(int j=1;j<=siz;j++)
ans[j][p%j]=ans[j][p%j]-val[p]+k;
val[p]=k;
}
}
return 0;
}