• UESTC


    题目链接

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

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

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

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

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

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

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

    Input

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

    接下来QQ行,每行三个整数,首先输入一个tt,如果tt是11,那么输入p,xp,x,表示卿学姐攻击了pp这个位置的士兵,并造成了xx的伤害。如果tt是22,那么输入L,RL,R,表示卿学姐想知道现在[L,R][L,R]闭区间内,受伤最严重的士兵受到的伤害。

    1N1000001≤N≤100000

    1Q1000001≤Q≤100000

    1pN1≤p≤N

    1x1000001≤x≤100000

    1LRN1≤L≤R≤N

    Output

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

    Sample Input

    5 4
    2 1 2
    1 2 4
    1 3 5
    2 3 3
    

    Sample Output

    0
    5
    

    Hint

    注意可能会爆int哦

    分析: 

     单点更新,区间查询最大值。单纯的线段树无法完成此功能,我们可以考虑一下分块,将复杂度下降。分块统计每一块的最大值,详细看代码

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long LL;
    const int maxn = 1e5+5;
    const int mod = 10000007;
    
    int belong[maxn],block,num,l[maxn],r[maxn];
    int n,q;
    long long a[maxn],Max[maxn];
    void init(){
        memset(belong,0,sizeof(belong));
        memset(a,0,sizeof(a));
        memset(Max,0,sizeof(Max));
        block = sqrt(n);
        num = n/block;
        if(n%block) num++;
        for(int i=1;i<=n;i++){
            belong[i]=(i-1)/block+1;
        }
    
        for(int i=1;i<=num;i++){
            l[i]=(i-1)*block+1;
            r[i]=i*block;
        }
        r[num]=n;
    }
    void update(int p,int x){
        a[p]+=x;
        Max[belong[p]]=max(a[p],Max[belong[p]]);
    }
    
    long long ask(int L,int R){
        long long res = 0;
        if(belong[L]==belong[R]){ //特判同一块里的情况
            for(int i=L;i<=R;i++) res = max(res,a[i]);
            return res;
        }
        for(int i=L;i<=r[belong[L]];i++) res = max(res,a[i]);
        for(int i=belong[L]+1;i<=belong[R]-1;i++) res = max(res,Max[i]);
        for(int i=l[belong[R]];i<=R;i++) res = max(res,a[i]);
        return res;
    }
    int main(){
    
        scanf("%d%d",&n,&q);
        init();
        int t,p,x;
        while(q--){
            scanf("%d%d%d",&t,&p,&x);
            if(t==1){
                update(p,x);
            }else{
                printf("%lld
    ",ask(p,x));
            }
        }
        return 0;
    }
  • 相关阅读:
    python Exception中的raise、assert
    python循环语句与其他编程语言不同之处
    【转】最大似然估计
    尝试发表代码
    奇异分解(SVD)
    Python学习笔记3-string
    梯度下降法
    前后端分离
    Trie树
    HashMap的工作原理以及代码实现,为什么要转换成红黑树?
  • 原文地址:https://www.cnblogs.com/fht-litost/p/8531417.html
Copyright © 2020-2023  润新知