题意:第一行一个n,表示数的个数,下面一行n个数是初始数值,然后一行一个数m代表m个询问数,1 a b k c代表a到b区间内每隔k个数加c;2 a代表询问a出的值。树状数组可解,如果是对a到b区间内的所有数加c用树状数组很好解决,对于此题,由于是a、b间每隔k个数才进行更新,k的值在10之内,取余数也比较少可以对对应每个k建一棵树,对应的每个余数进行更新,数组定义就变成了C[N][11][11];具体代码:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 50010;
int c[N][11][11], numb[N];
int lowbit(int x)
{
return x&(-x);
}
void update(int x, int k, int add, int mod)
{
while(x > 0)
{
c[x][k][mod] += add;
x -= lowbit(x);
}
}
int sum(int x, int a)
{
int s = 0;
while(x < N)
{
for(int i=1; i<11; ++i)
s += c[x][i][a%i];
x += lowbit(x);
}
return s;
}
int main()
{
int n, m, key;
while(~scanf("%d", &n))
{
for(int i=1; i<=n; ++i)
scanf("%d", &numb[i]);
memset(c, 0, sizeof(c));
scanf("%d", &m);
while(m--)
{
scanf("%d", &key);
if(key == 1)
{
int a, b, k, add;
scanf("%d%d%d%d", &a, &b, &k, &add);
update(a-1, k, -add, a%k);
update(b, k, add, a%k);
}
else
{
int a;
scanf("%d", &a);
printf("%d\n", numb[a] + sum(a, a));
}
}
}
return 0;
}