hdu(4267)A Simple Problem with Integers(三维树状数组)

  这道题拿过来感觉很蒙 , 因为以前做的都是点更新询问区间 , 或是区间更新询问点 , 这道题是在[a,b]区间内隔k个数更新一次( (i - a) % k == 0即i%k==a%k),  对于树状数组来说按照一维的方式定义, 后面在加上两维  c[i][k][i%k]  (a<=i<=b), 相当于在一维c[i]每个节点加入了一些信息,来记录每次更新,询问时候再加上原数组即可得到结果。

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>

using namespace std ;
const int maxn = 50005;
int num[maxn];
int c[maxn][11][11];
int lowbit(int x){
    return x&(-x);
}
void update(int v,int k,int ik,int val){
    for(int i = v;i > 0;i-=lowbit(i))
        c[i][k][ik] += val;
}
int query(int v){
    int ans = 0;
    for(int i = v;i < maxn;i+=lowbit(i)){
        for(int j = 1;j <= 10;j++)
            ans += c[i][j][v%j];
    }
    return ans;
}
int main(){
    int n;
    while(~scanf("%d",&n)){
        memset(c,0,sizeof(c));
        for(int i = 1;i <= n;i++)
            scanf("%d",num+i);
        int q;
        scanf("%d",&q);
        while(q--){
            int f,a,b,k,c;
            scanf("%d",&f);
            if(f == 1){
                scanf("%d%d%d%d",&a,&b,&k,&c);
                update(a-1,k,a%k,-c);
                update(b,k,a%k,c);
            }
            else{
                scanf("%d",&a);
                printf("%d\n",query(a)+num[a]);
            }
        }
    }
    return 0 ;
}
原文地址:https://www.cnblogs.com/Roly/p/3057846.html