题目:http://acm.hdu.edu.cn/showproblem.php?pid=4267
线段树,注意k很小,更新优化。
//STATUS:C++_AC_218MS_3904KB
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<queue>
#include<math.h>
#include<map>
using namespace std;
const int MAX=50010,INF=200000000;
const double esp=1e-6;
struct info{
int k,mod,c;
info *next;
}*seg[MAX<<2];
void update(int l,int r,int rt);
void query(int l,int r,int rt);
int n,num[MAX],a,b,k,c,ans;
int main()
{
// freopen("in.txt","r",stdin);
int i,op,q;
while(~scanf("%d",&n))
{
memset(seg,0,sizeof(seg));
for(i=1;i<=n;i++)
scanf("%d",&num[i]);
scanf("%d",&q);
while(q--)
{
scanf("%d",&op);
if(op==1){
scanf("%d%d%d%d",&a,&b,&k,&c);
update(1,n,1);
}
else {
ans=0;
scanf("%d",&a);
query(1,n,1);
printf("%d\n",num[a]+ans);
}
}
}
return 0;
}
void update(int l,int r,int rt)
{
if(a<=l && r<=b){
int mod=k-(l-a)%k; //更新优化
if(mod>=k)mod-=k;
for(info* q=seg[rt];q!=NULL;q=q->next)
{
if(q->k==k && q->mod==mod){
q->c+=c;
return;
}
}
info* p=new info();
p->k=k,p->c=c,p->mod=mod;
p->next=seg[rt];
seg[rt]=p;
return;
}
int mid=(l+r)>>1;
if(a<=mid)update(l,mid,rt<<1);
if(b>mid)update(mid+1,r,rt<<1|1);
}
void query(int l,int r,int rt)
{
info *p=NULL;
for(p=seg[rt];p!=NULL;p=p->next){
if((a-l)%p->k==p->mod)ans+=p->c;
}
if(l==r)return;
int mid=(l+r)>>1;
if(a<=mid)query(l,mid,rt<<1);
else query(mid+1,r,rt<<1|1);
}