树状数组写的
真不知道线段树的怎么写额。。写了一遍TLE就不知道怎么改了→ →
(i - a) % k == 0这个分析看题解才懂的。。
变为i%k==a%k 的形式 发现只要把c变为三维数组就行了
更新时 c[n][k][a%k] 这样就能实现区域更新了
在计算时 c[n][i][i%k] 这样就满足了 i%k==a%k 的条件 把所有满足条件的加起来就A了。。
#include <stdio.h>
#include <string.h>
const int MAXN = 50005;
int lowbit(int x)
{
return x&(-x);
}
int c[MAXN][11][11],n,a[MAXN];
void modi(int pos,int val,int k,int mod)
{
while(pos>0)
{
c[pos][k][mod]+=val;
pos-=lowbit(pos);
}
}
int cal(int pos,int p)
{
int sum=0;
while(pos<=n)
{
for(int i=0;i<10;i++)
{
int k=i+1;
sum+=c[pos][k][p%k];
}
pos+=lowbit(pos);
}
return sum;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("4267in.txt","r",stdin);
#endif
int l,r,k,val;
while(scanf("%d",&n)==1)
{
memset(c,0,sizeof(c));
for(int i=0;i<n;i++)
scanf("%d",&a[i+1]);
int com;
scanf("%d",&com);
for(int i=0;i<com;i++)
{
int tmp;
scanf("%d",&tmp);
if(tmp==1)
{
scanf("%d%d%d%d",&l,&r,&k,&val);
modi(r,val,k,l%k);
modi(l-1,-val,k,l%k);
}
else if(tmp==2)
{
scanf("%d",&l);
printf("%d\n",cal(l,l)+a[l]);
}
}
}
return 0;
}