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