为了这题学习了树状数组
三维树状数组
(i-a)%k==0等价于i%k==a%k,所以可以把不同位置按取K的模放到一组里
ar[x][k][mod]表示在x位置k=k时,余数为mod的值,
求一个位置的值,只要遍历与v%i相等的数的和就行了
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 50005
int ar[N][11][10],y[N];
int n,m;
void init()
{
int i,j,k;
for(i=1;i<=n;i++)
for(j=1;j<11;j++)
for(k=0;k<10;k++)
ar[i][j][k]=0;
}
int lowbit(int x)
{
return x&-x;
}
void update(int x,int mod,int k,int add)
{
while(x>0)
{
ar[x][k][mod]+=add;
x-=lowbit(x);
}
}
int getsum(int x)
{
int v=x,i,sum=0;
while(x<=n)
{
for(i=1;i<=10;i++)
{
sum+=ar[x][i][v%i];
}
x+=lowbit(x);
}
return sum;
}
int main()
{
int i,j,a,aa,b,k,c;
while(scanf("%d",&n)!=EOF)
{
init();
for(i=1;i<=n;i++)
{
scanf("%d",&y[i]);
}
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%d",&a);
if(a==1)
{
scanf("%d%d%d%d",&aa,&b,&k,&c);
update(b,aa%k,k,c);
update(aa-1,aa%k,k,-c);
}
else
{
scanf("%d",&aa);
printf("%d\n",getsum(aa)+y[aa]);
}
}
}
return 0;
}