HDU4267 A Simple Problem with Integers【树状数组】

A Simple Problem with Integers

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


 

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

问题链接HDU4267 A Simple Problem with Integers

问题描述

  对于一个给定的整数序列,对其进行的操作有两种,一种是在[a, b]内,对(i - a) % k == 0 的所有值加上c,另一种是查询某个位置的值。

问题分析

  这个问题用树状数组来解决。

  由于k<=10,一共有1+2+3+...+10 = 55种余数,所以可以开55个树状数组,用z[k][mod][i]表示i % k == mod,便于询问时候减少循环次数。

  区间【a, b】内的更新+x,就在a的位置+x,然后在b+1的位置-x。

程序说明:(略)

参考链接:(略)

题记:(略)

AC的C++语言程序如下:

/* HDU4267 A Simple Problem with Integers */

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

using namespace std;

const int N = 50000;
const int K = 10;
int n, z[K + 1][K + 1][N + 1];
int v[N + 1];

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

// 更新函数
void update(int k, int mod, int pos, int val)
{
    while(pos) {
        z[k][mod][pos] += val;
        pos -= lowbit(pos);
    }
}

// 求和函数
int sum(int k, int pos)
{
    int sum = 0;
    while(pos <= n) {
        for(int j=1; j <= K; j++)
            sum += z[j][k%j][pos];
        pos += lowbit(pos);
    }
    return sum;
}

int main()
{
    while(~scanf("%d", &n)) {
        memset(z, 0, sizeof(z));

        for(int i = 1; i <= n; i++)
            scanf("%d", &v[i]);

        int q;
        scanf("%d", &q);
        while(q--) {
            int op, a, b, k, c;
            scanf("%d", &op);
            if(op == 1) {
                scanf("%d%d%d%d", &a, &b, &k, &c);
                update(k, a % k, b, c);
                update(k, a % k, a - 1, -c);
            } else if(op == 2) {
                scanf("%d", &a);
                int ans = sum(a, a);
                printf("%d\n", ans + v[a]);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/tigerisland45/article/details/81489621