转载:http://www.cnblogs.com/programCaiCai/archive/2012/09/08/HDU4267.html
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
using namespace std;
#define maxn 50010
int a[maxn],n,block_size;
struct Flag
{
int vis[11];
int x[11][11];
void clear(){
memset(vis,0,sizeof(vis));
memset(x,0,sizeof(x));
}
}flag[500];
void build()
{
block_size=(int)sqrt(n*1.0+1e-10);
int block_num=n/block_size+(n%block_size!=0);
for(int i=0;i<block_num;i++) flag[i].clear();
for(int i=0;i<n;i++) scanf("%d",&a[i]);
}
void pushdown(int block_no)
{
int sta=block_no*block_size;
int ed=(block_no+1)*block_size;
for(int i=1;i<=10;i++)
if(flag[block_no].vis[i]){
for(int j=0;j<i;j++)
if(flag[block_no].x[i][j]){
int tmp=sta;
while(tmp%i!=j) tmp++;
for(int r=tmp;r<ed;r+=i) a[r]+=flag[block_no].x[i][j];
}
}
flag[block_no].clear();
}
int shl(int block_no,int l,int k)
{
int ret=0,sta=block_no*block_size;
while((sta+ret-l)%k!=0) ret++;
return ret;
}
void update(int l,int r,int k,int c)
{
int lx=l/block_size,rx=r/block_size;
if(lx==rx){
pushdown(lx);
for(int i=l;i<=r;i+=k) a[i]+=c;
}else{
pushdown(lx);
pushdown(rx);
int sta=(lx+1)*block_size;
for(int i=l;i<sta;i+=k) a[i]+=c;
sta=rx*block_size;
for(int i=shl(rx,l,k)+sta;i<=r;i+=k) a[i]+=c;
for(int i=lx+1;i<rx;i++)
{
flag[i].vis[k]=1;
flag[i].x[k][l%k]+=c;
}
}
}
int query(int pos)
{
pushdown(pos/block_size);
return a[pos];
}
int main()
{
int cmd,l,r,k,c,q;
while(scanf("%d",&n)==1)
{
build();
scanf("%d",&q);
while(q--){
scanf("%d%d",&cmd,&l);
if(cmd==1){
scanf("%d%d%d",&r,&k,&c);
update(l-1,r-1,k,c);
}else printf("%d\n",query(l-1));
}
}
return 0;
}