问题 A: 数列操作
时间限制: 1 Sec 内存限制: 128 MB
提交: 63 解决: 22
[提交][状态][讨论版][命题人:quanxing][Edit] [TestData]
题目链接:http://acm.ocrosoft.com/problem.php?cid=1688&pid=0
题目描述
给定n个数列,规定有两种操作,一是修改某个元素,二是求子数列[A,B]的连续和。数列的元素个数最多10万个,询问操作最多10万次。
输入
第一行2个整数n,m(n表示输入n个数列,m表示有m个操作)
第二行输入n个数列。
接下来M行,每更好行有三个数k,a,b(k=0表示求子数列[a,b]的和,k=1表示第a个数列加b)
输出
输出若干行数字,表示每次K=0时对应输出一个子数列[a,b]的连续和。
样例输入
10 5
1 2 3 4 5 6 7 8 9 10
1 1 5
0 1 3
0 4 8
1 7 5
0 4 8
样例输出
11
30
35
思路:树状数组所有操作加上去就行了
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
int A[maxn], C[maxn];
int n, m;
int lowbit(int t)//t转换为二进制后,有末尾连续0共k个,返回2^k次方
{
return t & -t;
}
void add(int x, int y)//单点修改
{
for (int i = x; i <= n; i += lowbit(i))
{
C[i] += y;
}
}
int sum(int x)//区间求和
{
int ans = 0;
for (int i = x; i > 0; i -= lowbit(i))
{
ans += C[i];
}
return ans;
}
int main()
{
scanf("%d%d", &n, &m);//用scanf,会卡cin和cout
for (int i = 1; i <= n; i++)scanf("%d", &A[i]), add(i, A[i]);
while (m--)
{
int k;
int a, b;
scanf("%d%d%d", &k, &a, &b);
if (k == 1)
{
add(a, b);
}
else
{
printf("%d\n", sum(b) - sum(a - 1));
}
}
}