2016 UESTC Training for Data Structures A - 卿学姐与公主 线段树

A - 卿学姐与公主

Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
Submit  Status

某日,百无聊赖的卿学姐打开了某1区的某魔幻游戏

在这个魔幻的游戏里,生活着一个美丽的公主,但现在公主被关押在了魔王的城堡中。

英勇的卿学姐拔出利刃冲向了拯救公主的道路。

走过了荒野,翻越了高山,跨过了大洋,卿学姐来到了魔王的第一道城关。

在这个城关面前的是魔王的精锐部队,这些士兵成一字排开。

卿学姐的武器每次只能攻击一个士兵,并造成一定伤害,卿学姐想知道某时刻从 L R 这个区间内,从开始到现在累计受伤最严重的士兵受到的

伤害。

最开始每个士兵的受到的伤害都是0

Input

第一行两个整数 N,Q 表示总共有 N 个士兵编号从 1 1 N ,和 Q 个操作。

接下来 Q 行,每行三个整数,首先输入一个 t ,如果 t t 1 ,那么输入 p,x ,表示卿学姐攻击了 p 这个位置的士兵,并造成了 x 的伤害。

如果 t t 2 2,那么输入 L,R 表示卿学姐想知道现在 [L,R] 闭区间内,受伤最严重的士兵受到的伤害。

1N100000

1Q100000

1pN

1x100000

1LRN

Output

对于每个询问,回答相应的值

Sample input and output

Sample Input Sample Output
5 4
2 1 2
1 2 4
1 3 5
2 3 3
0
5

Hint

注意可能会爆int哦

Source

2016 UESTC Training for Data Structures  Problem A

My Solution

裸的的线段树,主要是Top[]数组开的足够大,且不太大

2^(n-1) = k; ==> k = logn + 1

用等比数列求和公式sum = 2*n - 1

但一般开成4*maxn就可以了,如果要卡一卡内存,可以试试2.5*maxn , 2.6*maxn , 3*maxn etc.

复杂度 O(nlogn)

#include <iostream>
#include <cstdio>
#include <cstring>
typedef long long LL;
using namespace std;
const int maxn = 100000+8;

LL Cover[4*maxn], Top[4*maxn];
int size;

LL _Query(int a,int b,int l,int r,int Ind){
    if(a <= l && b >= r) return Top[Ind];
    int mid = (l+r)>>1;
    LL ret = Cover[Ind];
    if(a <= mid) ret = max(ret, _Query(a, b, l, mid, Ind<<1));
    if(b > mid) ret = max(ret, _Query(a,b,mid+1,r,(Ind<<1)+1));
    return ret;
}

void _Modify(int a,int l,int r,int Ind,int d){
    if(l == r && l == a){
        Cover[Ind] += d;
        Top[Ind] += d;
        return;
    }
    int mid = (l+r)>>1;
    if(a <= mid) _Modify(a,l,mid,Ind<<1,d);
    else _Modify(a,mid+1,r,(Ind<<1)+1,d);
    Top[Ind] = max(Top[Ind<<1], Top[(Ind<<1)+1]);
}

LL Query(int a,int b) {return _Query(a,b,1,size,1);}
void Modify(int a,int d){return _Modify(a,1,size,1,d);}

int main()
{
    #ifdef LOCAL
    freopen("a.txt", "r", stdin);
    #endif // LOCAL
    memset(Top, 0, sizeof Top); memset(Cover, 0, sizeof Cover);
    int  n,q;
    scanf("%d", &n); size = n;
    Modify(1, 0);

    int t, x, y;
    scanf("%d", &q);
    while(q--){
        scanf("%d%d%d", &t, &x, &y);
        if(t == 1) Modify(x,y);
        else printf("%lld\n", Query(x,y));
    }
    return 0;
}

Thank you!

                                                                                                                                               ------from ProLights

你可能感兴趣的:(线段树,ACM,for,Data,Training,uestc,2016,structures)