HDU 4267 A Simple Problem with Integers

题目大意:对一个长度为n(n <= 50000)的数列A进行m(m <= 50000)次操作(2种):
  1:给定a,b,k,c四个整数,在[a , b] 区间满足a<=i<=b && (i-a)% k == 0的数加c(1<=k<=10);         

  2:给定整数a,求当前A[a];

题解:首先,这是线段修改,单点查询的问题,可以用树状数组解决,但是由于数据不是连续的所以,采用划分成多个树状数组的方式来完成。我们按照数列的首项和公差将其划分为55个树状数组,然后进行统计。

#include <cstdio>
#include <iostream>
using namespace std;
const int MAXN=50005;
int c[105][MAXN],begin[MAXN],n,m;
void update(int k,int x,int val){while(x<=n)c[k][x]+=val,x+=x&-x;}
int getsum(int pos){
    int s=0;
    for(int i=1;i<=10;i++){
        int k=10*(i-1)+pos%i,x=pos;
        while(x)s+=c[k][x],x-=x&-x;
    }return s+begin[pos];
}
int main(){
    int a,b,k,num,q;
    while(~scanf("%d",&n)){
         memset(c,0,sizeof(c));
         for(int i=1;i<=n;i++)scanf("%d",&begin[i]);
         scanf("%d",&m);
         while(m--){
             scanf("%d",&q);
             if(q==1){
                 scanf("%d%d%d%d",&a,&b,&k,&num);
                 b-=(b-a)%k;
                 update(10*(k-1)+a%k,a,num);
                 update(10*(k-1)+a%k,b+1,-num);
             }else scanf("%d",&a),printf("%d\n",getsum(a));
         }
    }
    return 0;
}
posted @ 2014-04-09 14:50  forever97  阅读(137)  评论(0编辑  收藏  举报