1.对于每个z开一颗线段树
2.因为周期比较小,对于每一个节点维护在周期的不同位置区间和
#include<iostream>
#include<cstdio>
using namespace std;
#define ll o<<1
#define rr o<<1|1
#define mid (l+r)/2
typedef __int64 LL;
const int N=1e5+10;
LL cc[5][N<<2][10];int len[5]={2,4,6,8,10};
LL aa[N];
void pushup(int l,int r,int o){
for(int id=0;id<5;id++)
for(int i=0;i<len[id];i++){
cc[id][o][i]=cc[id][ll][i]+cc[id][rr][(i+mid-l+1)%len[id]];
}
}
int getf(int i,int id){
if(i==0)return 2;
if(i>id+2)i=2*(id+2)-i;
return i;
}
void build(int l,int r,int o){
if(l==r){
for(int id=0;id<5;id++){
for(int i=0;i<len[id];i++){
cc[id][o][i]=aa[l]*getf(i,id);
}
}return ;
}
build(l,mid,ll);build(mid+1,r,rr);
pushup(l,r,o);
}
void update(int l,int r,int o,int x,int v){
if(l==r){
aa[l]=v;
for(int id=0;id<5;id++)
for(int i=0;i<len[id];i++){
cc[id][o][i]=aa[l]*getf(i,id);
}return ;
}
if(x<=mid)update(l,mid,ll,x,v);
else update(mid+1,r,rr,x,v);
pushup(l,r,o);
}
int L,R;LL ans;
void query(int l,int r,int o,int id){
if(L<=l&&r<=R){
ans+=cc[id][o][(l-L+1)%len[id]];return ;
}
if(L<=mid)query(l,mid,ll,id);
if(R>mid)query(mid+1,r,rr,id);
}
int main(){
#ifdef DouBi
freopen("in.cpp","r",stdin);
#endif // DouBi
int n;while(scanf("%d",&n)!=EOF){
for(int i=1;i<=n;i++)scanf("%I64d",&aa[i]);
build(1,n,1);
int m;scanf("%d",&m);
for(int i=0;i<m;i++){
int t;scanf("%d",&t);
//printf("%d\n",t);
if(t==1){
int p,v;scanf("%d%d",&p,&v);
update(1,n,1,p,v);
}
else {
int l,r,z;scanf("%d%d%d",&l,&r,&z);
L=l,R=r;z-=2;
ans=0;
//printf("%d\n",z);
query(1,n,1,z);
printf("%I64d\n",ans);
}
}
}
return 0;
}