一开始看着题目毫无思路…
只有一个暴力才能维持的了10分的样子…
想着打开时的标签:分块….
死活不会统计…
然后弃疗…
换了一个方向思考,,,
首先如果查询
x>y
x
>
y
肯定都不用管..直接输出0
考虑模数在
n
n
范围以内,那么对于模数特别大的情况,发现每个池子的数很少,可以暴力统计。
对于模数小的情况,发现他的预处理很简单的样子…
然后就发现,,,把大于的数暴力处理是在
O(n‾√)
O
(
n
)
的,把小于
n‾√
n
的数更新也是
O(n‾√)
O
(
n
)
发现这样处理时间
O(nn‾√)
O
(
n
n
)
c++代码如下:
#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i = x; i <= y ; ++ i)
#define repd(i,x,y) for(register int i = x; i >= y ; -- i)
using namespace std;
template<typename T>inline void read(T&x)
{
char c;int sign = 1;x = 0;
do { c = getchar(); if( c == '-' ) sign = -1; }while(!isdigit(c));
do { x = x * 10 + c - '0'; c =getchar(); } while(isdigit(c));
x *= sign;
}
const int N = 400;
int pre[N][N],a[N*N];
int n,m,d;
inline void PRE()
{
rep(j,1,n)
rep(i,1,d)
pre[i][j%i] += a[j];
}
inline void solve(int x,int y)
{
if(y >= x) return void(puts("0"));
if(x > d)
{
int ans = 0,now = y;
while(now <= n)
{
ans += a[now];
now += x;
}
printf("%d\n",ans);
}
else printf("%d\n",pre[x][y]);
}
inline void update(int x,int y)
{
rep(i,1,d)
pre[i][x % i] += y - a[x];
a[x] = y;
}
char op[2];
int x,y;
int main()
{
read(n); read(m);
d = sqrt(n);
rep(i,1,n) read(a[i]);
PRE();
rep(i,1,m)
{
scanf("%s",op);
if( op[0] == 'A' )
{
read(x); read(y);
solve(x,y);
}
else
{
read(x); read(y);
update(x,y);
}
}
return 0;
}