【vijos1659】河蟹王国 线段树<区间修改+区间最大值>

描述

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

输入格式

第一行是一个数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]。

输出格式

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

样例输入

5

1

2

3

4

5

3

2 1 4

1 1 3 3

2 3 5

样例输出

4

6

限制

每个测试点1s。

代码

  1 #include <cstdio>
  2 #include <cmath>
  3 #include <cstring>
  4 #include <ctime>
  5 #include <iostream>
  6 #include <algorithm>
  7 #include <set>
  8 #include <vector>
  9 #include <queue>
 10 #include <typeinfo>
 11 #include <map>
 12 #include <stack>
 13 typedef long long ll;
 14 using namespace std;
 15 inline ll read()
 16 {
 17     ll x=0,f=1;
 18     char ch=getchar();
 19     while(ch<‘0‘||ch>‘9‘)
 20     {
 21         if(ch==‘-‘)f=-1;
 22         ch=getchar();
 23     }
 24     while(ch>=‘0‘&&ch<=‘9‘)
 25     {
 26         x=x*10+ch-‘0‘;
 27         ch=getchar();
 28     }
 29     return x*f;
 30 }
 31 //**************************************************************************************
 32 struct ss
 33 {
 34     int l,r,v,tag;
 35 }tr[100001*4];
 36 int n,a[100005];
 37 void build(int k,int l,int r)
 38 {
 39     tr[k].l=l;
 40     tr[k].r=r;
 41     if(l==r) {tr[k].v=a[l];return ;}
 42     int  mid=(l+r)>>1;
 43     build(k<<1,l,mid);
 44     build(k<<1|1,mid+1,r);
 45    // tr[k].v=tr[k<<1].v+tr[k<<1|1].v;
 46     tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
 47 }
 48 void pushdown(int k)
 49 {
 50     tr[k<<1].tag+=tr[k].tag;
 51     tr[k<<1|1].tag+=tr[k].tag;
 52     tr[k<<1].v+=tr[k].tag;
 53     tr[k<<1|1].v+=tr[k].tag;
 54     tr[k].tag=0;
 55 }
 56 void update(int k,int l,int r,int x)
 57 {
 58     if(l==tr[k].l&&r==tr[k].r)
 59     {
 60         tr[k].tag+=x;
 61         tr[k].v+=x;
 62         return;
 63     }
 64     if(tr[k].tag) pushdown(k);
 65     int mid=(tr[k].l+tr[k].r)>>1;
 66     if(r<=mid)update(k<<1,l,r,x);
 67     else if(l>mid)update(k<<1|1,l,r,x);
 68     else {
 69         update(k<<1,l,mid,x);
 70         update(k<<1|1,mid+1,r,x);
 71     }
 72     tr[k].v=max(tr[k<<1].v,tr[k<<1|1].v);
 73 }
 74 int ask(int k,int l,int r)
 75 {
 76     if(l==tr[k].l&&tr[k].r==r)
 77     {
 78         return tr[k].v;
 79     }
 80     if(tr[k].tag) pushdown(k);
 81     int mid=(tr[k].l+tr[k].r)>>1;
 82     if(r<=mid) return ask(k<<1,l,r);
 83     else if(l>mid)return ask(k<<1|1,l,r);
 84     else {
 85         return max(ask(k<<1,l,mid),ask(k<<1|1,mid+1,r));
 86     }
 87 }
 88 int main()
 89 {
 90
 91     scanf("%d",&n);
 92     for(int i=1;i<=n;i++)
 93     {
 94         scanf("%d",&a[i]);
 95     }
 96     build(1,1,n);
 97     int q;
 98     scanf("%d",&q);
 99     for(int i=1;i<=q;i++)
100     {
101         int t;
102         scanf("%d",&t);
103         if(t==2)
104         {
105             int x,y;
106             scanf("%d%d",&x,&y);
107             printf("%d\n",ask(1,x,y));
108         }
109         else {
110             int x;int y;int c;
111             scanf("%d%d%d",&x,&y,&c);
112             update(1,x,y,c);
113         }
114     }
115     return 0;
116 }
时间: 2024-08-28 15:40:24

【vijos1659】河蟹王国 线段树<区间修改+区间最大值>的相关文章

vijos 1659 河蟹王国 线段树区间加、区间查询最大值

河蟹王国 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 https://vijos.org/p/1659 Description 河蟹王国有一位河蟹国王,他的名字叫羊驼.河蟹王国富饶安定,人们和谐相处.有一天,羊驼国王心血来潮,想在一部分人中挑出最和谐的人.于是,羊驼国王将 他的子民排成了一列(==!!b汗~好长呀).每个人都有一个初始的和谐值.羊驼国王每次会选择一个区间[L,R],这个区间中和谐值最大的人就是国王选 出的人.而且,在某一时间,区间[L

Lightoj 1348 Aladdin and the Return Journey (树链剖分)(线段树单点修改区间求和)

Finally the Great Magical Lamp was in Aladdin's hand. Now he wanted to return home. But he didn't want to take any help from the Genie because he thought that it might be another adventure for him. All he remembered was the paths he had taken to reac

Spoj 1716 Can you answer these queries III 线段树 单点修改 区间求最大子段和

题目链接:点击打开链接 == 原来写1的时候已经把更新函数写好了.. #include <cstdio> #include <iostream> #include <algorithm> #include <string.h> #include <math.h> #include <vector> #include <map> using namespace std; #define N 50050 #define Lso

树链剖分+线段树 单点修改 区间求和 模板

马上要去西安打邀请赛了,存下板子 首先是vector存图的: #include<bits/stdc++.h> using namespace std; #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mid int m = (l + r) >> 1 const int M = 2e5+10; int fa[M],dep[M],siz[M],son[M

HDOJ--4893--Wow! Such Sequence!【线段树+单点、区间更新】

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 题意:给你一个长度n的数列,初始都为0,有三种操作,第一种给第k个位置的数加d,第二种是查询区间 [l , r] 的总和,第三种是使区间 [l , r] 的值改为离它最近的那个斐波那契数的值. 我刚开始用sum数组存储节点的值,第三种操作是个区间更新,但是区间更新的值不一样,我就想当然的搜到最底部的节点来处理更新,果断T了.后来想了想,其实可以在节点上再加一个信息,就是这个值下次进行第三种操作要变

线段树2 求区间最小值

线段树2 求区间最小值 从数组arr[0...n-1]中查找某个数组某个区间内的最小值,其中数组大小固定,但是数组中的元素的值可以随时更新. 数组[2, 5, 1, 4, 9, 3]可以构造如下的二叉树(背景为白色表示叶子节点,非叶子节点的值是其对应数组区间内的最小值,例如根节点表示数组区间arr[0...5]内的最小值是1): 线段树的四种操作: 1.线段树的创建 2.线段树的查询 3.线段树的更新单节点 4.线段树的更新区间 直接上完整代码吧 1 #include <bits/stdc++.

UPC 2224 Boring Counting (离线线段树,统计区间[l,r]之间大小在[A,B]中的数的个数)

题目链接:http://acm.upc.edu.cn/problem.php?id=2224 题意:给出n个数pi,和m个查询,每个查询给出l,r,a,b,让你求在区间l~r之间的pi的个数(A<=pi<=B,l<=i<=r). 参考链接:http://www.cnblogs.com/zj62/p/3558967.html #include <iostream> #include <cstdio> #include <cstring> #incl

hdu - 4973 - A simple simulation problem.(线段树单点更新 + 区间更新)

题意:初始序列 1, 2, ..., n,m次操作(1 <= n,m<= 50000),每次操作可为: D l r,将区间[l, r]中的所有数复制一次: Q l r,输出区间[l, r]中同一数字个数的最大值. (0 <= r – l <= 10^8, 1 <= l, r <= 序列元素个数) 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4973 -->>因为区间内数字是依次递增的,所以可以以数字为叶建线段

【HDU】1754 I hate it ——线段树 单点更新 区间最值

I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 37448    Accepted Submission(s): 14816 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要