題意:第一行一個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;
}