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\n",ask(1,a,b));
        }
    }
    return 0;
}
时间: 2024-11-08 14:00:19

vijos 1659 河蟹王国 线段树区间加、区间查询最大值的相关文章

【vijos1659】河蟹王国 线段树&lt;区间修改+区间最大值&gt;

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

hdu1698 Just a Hook(线段树+区间修改+区间查询+模板)

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 54923    Accepted Submission(s): 25566 Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of

线段树区间加模板

#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #define LL long long #define l(x) (x<<1) #define r(x) ((x<<1)|1) using namespace std; struct Tre {

POJ 3468 A Simple Problem with Integers 线段树 区间更新 区间查询

题目链接: http://poj.org/problem?id=3468 题目描述: 一组数列, 可进行一段区间加上某一个数, 和区间查询 解题思路: 线段树, 之前的那道题是求总区间直接输出sum[1] 就可以了, 这次有了区间查询, 同理, 查询的时候Pushdown 代码: #include <iostream> #include <cstdio> #include <string> #include <vector> #include <map

SPOJ GSS2 - Can you answer these queries II(线段树 区间修改+区间查询)(后缀和)

GSS2 - Can you answer these queries II #tree Being a completist and a simplist, kid Yang Zhe cannot solve but get Wrong Answer from most of the OI problems. And he refuse to write two program of same kind at all. So he always failes in contests. When

hihocoder1080线段树+区间修改+区间查询+多个懒标记

题目链接:http://hihocoder.com/problemset/problem/1080 对于这种不止一个懒标记的线段树,只要弄清楚各种操作和各种懒标记间的关系就OK了. 我的代码: 1 #include <cstdio> 2 3 using namespace std; 4 5 #define MAXN 100005 6 7 int p[MAXN]; 8 9 struct segNode 10 { 11 int left, right, sum, dd, vv; 12 bool l

线段树 区间加

#include<iostream> #include<queue> #include<cstdio> #include<math.h> #include<cstring> #include<algorithm> using namespace std; int n,Q; long long ans; long long sum[4000009]; int dx[4000009]; int a[2000009]; void build

CDOJ 1057 秋实大哥与花 线段树 区间更新+区间查询

链接: I - 秋实大哥与花 Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%lld & %llu Submit Status Practice UESTC 1057 Appoint description:  System Crawler  (2016-04-19) Description 秋实大哥是一个儒雅之人,昼听笙歌夜醉眠,若非月下即花前. 所以秋实大哥精心照料了很多花朵.现在所有的花朵排成了一行,每朵花有一

【模板】线段树 区间修改+区间查询

题目大意:维护一个长度为 N 的序列,支持区间修改.区间查询两种操作. 代码如下 #include <bits/stdc++.h> using namespace std; const int maxn=1e6+10; inline int read(){ int x=0,f=1;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch)); do{x=x*10+ch-'0';ch=getchar();}while(isdigit(