HDU 4267 經典樹狀數組

題目鏈接


A Simple Problem with Integers

Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4005 Accepted Submission(s): 1245

Problem Description

Let A1, A2, … , AN be N elements. You need to deal with two kinds of operations. One type of operation is to add a given number to a few numbers in a given interval. The other is to query the value of some element.

Input

There are a lot of test cases.
The first line contains an integer N. (1 <= N <= 50000)
The second line contains N numbers which are the initial values of A1, A2, … , AN. (-10,000,000 <= the initial value of Ai <= 10,000,000)
The third line contains an integer Q. (1 <= Q <= 50000)
Each of the following Q lines represents an operation.
“1 a b k c” means adding c to each of Ai which satisfies a <= i <= b and (i - a) % k == 0. (1 <= a <= b <= N, 1 <= k <= 10, -1,000 <= c <= 1,000)
“2 a” means querying the value of Aa. (1 <= a <= N)

Output

For each test case, output several lines to answer all query operations.

Sample Input

4
1 1 1 1
14
2 1
2 2
2 3
2 4
1 2 3 1 2
2 1
2 2
2 3
2 4
1 1 4 2 1
2 1
2 2
2 3
2 4

Sample Output

1
1
1
1
1
3
3
1
2
3
4
1

Source
2012 ACM/ICPC Asia Regional Changchun Online

題意

  • 實現給兩種操作
    • 1 a b k c 給在[a , b]區間的所有滿足下標 (i-a)%k == 0的所有數都加上c
    • 2 a 查詢下標爲a的值

解法

  • (i-a)%k == 0 , 代表i%k == a%k ,根據這個和k就可以唯一確定該更新的樹狀數組(感覺好叼)
  • 爲了方便建11*10的樹狀數組,其實只要55個 ,這樣就維護了所有可能的情況 ,查詢的時候把所有情況加上就好了
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cassert>
using  namespace std ;

const int N = 5e4 + 11 ;

int tree[11][10][N] ; int arr[N] ;
int n ;

int lowbit(int x) {
    return x&-x ;
}

void init() {
    for(int i = 1 ; i <= n ; ++i) scanf("%d" ,&arr[i]) ;
    memset(tree ,0 ,sizeof(tree)) ;
}

void update(int k , int mod ,int a , int d) {
    for(int i = a ; i <= n ; i += lowbit(i)) tree[k][mod][i] += d ;
}

void query(int x) {
    int ans = arr[x] ;
    for(int i = 1 ; i <= 10 ; ++i) {
        for(int j = x ; j > 0 ; j -= lowbit(j)) {
            ans += tree[i][x%i][j] ;
        }
    }
    printf("%d\n" ,ans) ;
}

int main() {//freopen("data.in" , "r" , stdin) ;
    while(scanf("%d" ,&n)==1) {
        init() ;
        int m ;
        scanf("%d" , &m) ;
        int op , a ,b , c , d ;
        while(m--) {
            scanf("%d" ,&op) ;
            if(op == 1) {
                scanf("%d%d%d%d" ,&a ,&b ,&c ,&d) ;
                update(c , a%c , a , d) ;
                update(c , a%c , b+1 , -d) ;
            }else {
                scanf("%d" ,&a) ;
                query(a) ;
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章