cojs.tk(所有题目来源) 树状数组专练

1.求和问题

★   输入文件:sum.in   输出文件:sum.out   简单对比
时间限制:1.2 s   内存限制:128 MB

【问题描述
    在一个长度为n的整数数列中取出连续的若干个数,并求它们的和。
【输入格式】
    输入由若干行组成,第一行有一个整数n
    第二行有n个整数
    第三行有一个整数m
    下面m行,每行两个整数i与j(i<=j),表示求和的起始和终止位置。
【输出格式】

    输出有m行, 每行一个整数,表示这个数段数列的和。

【输入样例】
输入文件
8
2 3 4 7 8 9 10 234 
5
2 3
4 7
1 3
7 7 
7 8 
 
输出文件

34
9
10 
244
【数据规模】
对于40%的数据,n<=1000,m<=1000,数列中的数不超过32767,数列的和不超过10^9
对于70%的数据,n<=10000,m<=2*10^5,数列中的数不超过32767
对于100%的数据,n<=10000,m<=2*10^5,数列中的数不超过10^9
#define INF 10001
#include<iostream>
using namespace std;
#include<cstdio>
long long  tree[INF];
int n,m,a,b;
int lowbit(int k)
{
    return k&-k;
}
void add(int k,int num)
{
    while(k<=n)
    {
        tree[k]+=num;
        k+=lowbit(k);
    }
}
long long int count(int k)
{
    long long int sum=0;
    while(k)
    {
        sum+=tree[k];
        k-=lowbit(k);
    }
    return sum;
}
int main()
{
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    scanf("%d",&n);
    int x;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&x);
        add(i,x);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;++i)
    {
        scanf("%d%d",&a,&b);
        cout<<count(b)-count(a-1)<<endl;/*这才是区间a--b的和*/
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
 } 
View Code

2.数列操作

★☆   输入文件:shulie.in   输出文件:shulie.out   简单对比
时间限制:1 s   内存限制:160 MB

【问题描述】

 假设有一列数 {Ai }(1 ≤ i ≤ n) ,支持如下两种操作:

(1)将 A k 的值加 D 。( k, D 是输入的数)

(2) 输出 A s +A s+1 +…+A t 。( s, t 都是输入的数, S ≤ T )

根据操作要求进行正确操作并输出结果。

【输入格式】

     输入文件第一行一个整数 n(0<=n<=100000) , 第二行为 n 个整数,表示 {A i } 的初始值。

第三行为一个整数 m(0<=m<=150000) ,表示操作数。 下接 m 行,每行描述一个操作,有如下两种情况:

ADD k d ( 表示将 A k 加 d , 1<=k<=n , d 为整数 )

SUM s t (表示输出 A s +…+A t )

【输出格式】

    对于每一个 SUM 提问,输出结果

【输入输出样例】
 
输入:

4
1 4 2 3 
3
SUM 1 3 
ADD 2 50
SUM 2 3

输出:

7

56

#include<iostream>
using namespace std;
#include<cstdio>
string a="ADD";
int n,m;
#define INF 100100
long long int tree[INF];
int s,t;
int lowbit(int k)
{
    return k&-k;
}
void add(int k,int num)
{
    while(k<=n)
    {
        tree[k]+=num;
        k+=lowbit(k);
    }
}
long long int count(int k)
{
    long long int sum=0;
    while(k)
    {
        sum+=tree[k];
        k-=lowbit(k);
    }
    return sum;
}
int main()
{
    freopen("shulie.in","r",stdin);
    freopen("shulie.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&s);
        add(i,s);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;++i)
    {
        string l;
        cin>>l;
        scanf("%d%d",&s,&t);
        if(l==a)
        add(s,t);
        else cout<<count(t)-count(s-1)<<endl;
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/c1299401227/p/5342408.html