HDU 4267 A Simple Problem with Integers(树状数组)
3维树状数组,将单点更新转变为区间更新。
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 #define LL __int64 7 #define N 50002 8 int p[11][11][50011]; 9 int num[50011]; 10 int n; 11 int lowbit(int t) 12 { 13 return t&(-t); 14 } 15 void insert(int k,int a,int t,int d) 16 { 17 while(t < N) 18 { 19 p[k][a][t] += d; 20 t += lowbit(t); 21 } 22 } 23 LL getsum(int k,int a,int t) 24 { 25 LL ans = 0; 26 while(t > 0) 27 { 28 ans += p[k][a][t]; 29 t -= lowbit(t); 30 } 31 return ans; 32 } 33 int main() 34 { 35 int i,j,temp,m,a,b,k,c; 36 LL ans = 0; 37 while(scanf("%d",&n)!=EOF) 38 { 39 memset(p,0,sizeof(p)); 40 for(i = 1;i <= n;i ++) 41 scanf("%d",&num[i]); 42 scanf("%d",&m); 43 for(i = 1;i <= m;i ++) 44 { 45 scanf("%d",&temp); 46 if(temp == 1) 47 { 48 scanf("%d%d%d%d",&a,&b,&k,&c); 49 insert(k,a%k,a/k+1,c);//+1为了防止出现0 50 insert(k,a%k,a/k+(b-a)/k+2,-c);//区间更新将[a/k+1,a/k+(b-a)/k+1]都增加c 51 } 52 else 53 { 54 scanf("%d",&a); 55 ans = 0; 56 for(j = 1;j <= 10;j ++) 57 { 58 ans += getsum(j,a%j,a/j+1); 59 } 60 printf("%I64d\n",ans+num[a]); 61 } 62 } 63 } 64 return 0; 65 }