zoukankan      html  css  js  c++  java
  • vijos 1659 河蟹王国 线段树区间加、区间查询最大值

    河蟹王国

    Time Limit: 1 Sec  Memory Limit: 256 MB

    题目连接

    https://vijos.org/p/1659

    Description

    河蟹王国有一位河蟹国王,他的名字叫羊驼。河蟹王国富饶安定,人们和谐相处。有一天,羊驼国王心血来潮,想在一部分人中挑出最和谐的人。于是,羊驼国王将 他的子民排成了一列(==!!b汗~好长呀)。每个人都有一个初始的和谐值。羊驼国王每次会选择一个区间[L,R],这个区间中和谐值最大的人就是国王选 出的人。而且,在某一时间,区间[L',R']里的人会变得熟悉,因此他们每个人的和谐值都会上升一个相同的值C。羊驼国王想知道,对于每一次选择,他选 出的最大和谐值是多少。

    Input

    第一行是一个数N(1<=N<=100000),表示人数。

    接下来的N行,每行一个数,表示排成的序列第i个人和谐值的初始值。

    接下来是一个数M(1<=M<=100000),表示羊驼国王或他的子民有所活动(羊驼国王选择一个区间算一次,某区间里的人增长和谐值算一次)的总次数。

    接下来的M行,每行第一个是一个数K,K是1或2,若K=1,接下来有三个数L,R,C,表示区间[L,R]的所有人增加C的和谐值;若K=2,接下来有两个数L,R,表示国王选择了区间[L,R]。


    Output

    每次对于国王选择区间,输出选择区间里的最大和谐值。

    Sample Input

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

    Sample Output

    4 6

    HINT

    题意

      

    题解:

    啊,线段树,区间更新(加/减),区间查询最大值

    裸题,拍拍拍

    代码:

    //qscqesze
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 2000001
    #define mod 10007
    #define eps 1e-9
    //const int inf=0x7fffffff;   //无限大
    const int inf=0x3f3f3f3f;
    /*
    
    */
    //**************************************************************************************
    int n,q,a[100001];
    struct data{
       int l,r;
       long long mx;
       int tag;
    }tr[300001];
    void build(int k,int s,int t)
    {
        tr[k].l=s;tr[k].r=t;
        if(s==t){tr[k].mx=a[s];return;}
        int mid=(s+t)>>1;
        build(k<<1,s,mid);
        build(k<<1|1,mid+1,t);
        tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
    }
    void pushdown(int k)
    {
         tr[k<<1].tag+=tr[k].tag;
         tr[k<<1|1].tag+=tr[k].tag;
         tr[k<<1].mx+=tr[k].tag;
         tr[k<<1|1].mx+=tr[k].tag;
         tr[k].tag=0;
    }
    void update(int k,int a,int b,int x)
    {
        int l=tr[k].l,r=tr[k].r;
        if(a==l&&r==b)
        {
                 tr[k].tag+=x;
                 tr[k].mx+=x;
                 return;
                 }
        if(tr[k].tag)pushdown(k);
        int mid=(l+r)>>1;
        if(b<=mid)update(k<<1,a,b,x);
        else if(a>mid)update(k<<1|1,a,b,x);
        else 
        {
            update(k<<1,a,mid,x);
            update(k<<1|1,mid+1,b,x);
        }
        tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
    }
    long long ask(int k,int a,int b)
    {
        int l=tr[k].l,r=tr[k].r;
        if(a==l&&b==r){return tr[k].mx;}
        if(tr[k].tag)pushdown(k);
        int mid=(l+r)>>1;
        if(b<=mid)return ask(k<<1,a,b);
        else if(a>mid)return ask(k<<1|1,a,b);
        else return max(ask(k<<1,a,mid),ask(k<<1|1,mid+1,b));
     }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
           scanf("%d",&a[i]);
        build(1,1,n);
        scanf("%d",&q);
        for(int i=1;i<=q;i++)
        {
            int t,a,b,x;
            scanf("%d ",&t);
            if(t==1){
                scanf("%d%d%d",&a,&b,&x);
                   update(1,a,b,x);
            }
            else{
                scanf("%d %d",&a,&b);
                printf("%lld
    ",ask(1,a,b));
            }
        }
        return 0;
    }
  • 相关阅读:
    Python基础语法 第2节课(数据类型转换、运算符、字符串)
    python基础语法 第5节课 ( if 、 for )
    python基础语法 第4节课 (字典 元组 集合)
    Python基础语法 第3节课 (列表)
    A. Peter and Snow Blower 解析(思維、幾何)
    C. Dima and Salad 解析(思維、DP)
    D. Serval and Rooted Tree (樹狀DP)
    C2. Balanced Removals (Harder) (幾何、思維)
    B. Two Fairs 解析(思維、DFS、組合)
    D. Bash and a Tough Math Puzzle 解析(線段樹、數論)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4389863.html
Copyright © 2011-2022 走看看