HDU 4267 经典树状数组

来源:互联网 发布:南航 java岗位 编辑:程序博客网 时间:2024/06/05 11:22

题目链接


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) ;            }        }    }}
0 0