题目链接:Magician

题意:

给你一个长度为n的序列v,你需要对这个序列进行m次操作,操作一共有两种,输入格式为

type a b

1、如果type==0,你就需要输出[a,b]区间内的美丽序列中所有元素的和,要使得这个值尽可能大

2、如果type==1,你就需要把a位置的元素值改为b

区间[a,b]的美丽序列就是va,va+1...vb。你需要从中取出任意个元素,这些元素的位置必须是奇偶交替

例如给你一个序列1,2,3,4,5,6,7

你取出来的美丽序列就有可能使1,2,3,4,5,6,7或者1,4,5,6,7或者2,5,6,7

题解:

我们使用线段树,如果type==1的时候就修改就可以了。对于type==0的情况。我们可以维护四个值,分别是区间[a,b]内的美丽序列:

从一个偶数位置开始,到一个奇数位置截至,我们使用ab来代替

从一个奇数位置开始,到一个奇数位置截至,我们使用bb来代替

从一个偶数位置开始,到一个偶数位置截至,我们使用aa来代替

从一个奇数位置开始,到一个偶数位置截至,我们使用ba来代替

对于线段树上一个节点维护的值,我们把这个节点称为a,把它的左右节点称为b,c

a.ab=max(b.aa+c.bb,b.ab+c.ab);   如果左右子树合并
a.ab=max(a.ab,max(b.ab,c.ab)); 如果左右子树不合并

 

其他四个值的维护也是这样

代码:

#include <map>
#include <set>
#include <list>
#include <queue>
#include <deque>
#include <cmath>
#include <stack>
#include <vector>
#include <bitset>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5+10;
const int INF = 0x3f3f3f3f;
const double PI = 3.1415926;
const long long N = 1000006;
const double eps = 1e-10;
typedef long long ll;
#define qmh(x) ask()
#define mt(A, B) memset(A, B, sizeof(A))
#define lson L, mid, rt<<1
#define rson mid + 1, R, rt<<1|1
#define ls rt<<1
#define rs rt<<1|1
#define SIS std::ios::sync_with_stdiget_mod_new(z-x)o(false), cin.tie(0), cout.tie(0)
#define pll pair<long long, long long>
#define lowbit(abcd) (abcd & (-abcd))
#define max(a, b) ((a > b) ? (a) : (b))
#define min(a, b) ((a < b) ? (a) : (b))
struct node
{
ll aa,bb,ab,ba;
void Clear()
{
aa=bb=ab=ba=-INF;
}
} tree[400009],result;
int arr[100009]; void Merge(node &a,node b,node c)
{
a.aa=max(b.ab+c.aa,b.aa+c.ba);
a.aa=max(a.aa,max(b.aa,c.aa));
a.bb=max(b.ba+c.bb,b.bb+c.ab);
a.bb=max(a.bb,max(b.bb,c.bb));
a.ab=max(b.aa+c.bb,b.ab+c.ab);
a.ab=max(a.ab,max(b.ab,c.ab));
a.ba=max(b.bb+c.aa,b.ba+c.ba);
a.ba=max(a.ba,max(b.ba,c.ba));
} void build(int rt,int L,int R)
{
if(L==R)
{
tree[rt].Clear();
if(L&1) tree[rt].aa=arr[L];
else tree[rt].bb=arr[L];
return ;
}
int mid=(L+R)>>1;
build(rt<<1,L,mid),build(rt<<1|1,mid+1,R);
Merge(tree[rt],tree[rt<<1],tree[rt<<1|1]);
} void update(int rt,int L,int R,int pos,int val)
{
if(L==R)
{
tree[rt].Clear();
if(L&1) tree[rt].aa=val;
else tree[rt].bb=val;
return ;
}
int mid=(L+R)>>1;
if(pos<=mid) update(rt<<1,L,mid,pos,val);
else update(rt<<1|1,mid+1,R,pos,val);
Merge(tree[rt],tree[rt<<1],tree[rt<<1|1]);
} void query(int rt,int L,int R,int LL,int RR)
{
if(L>=LL&&R<=RR)
{
Merge(result,result,tree[rt]);
return ;
}
int mid=(L+R)>>1;
if(mid>=LL) query(rt<<1,L,mid,LL,RR);
if(RR>mid) query(rt<<1|1,mid+1,R,LL,RR);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) scanf("%d",&arr[i]);
build(1,1,n);
while(m--)
{
int type,l,r;
scanf("%d%d%d",&type,&l,&r);
if(type==1) update(1,1,n,l,r);
else
{
result.Clear();
query(1,1,n,l,r);
printf("%lld\n",max(max(result.aa,result.bb),max(result.ab,result.ba)));
}
}
}
return 0;
}

hdu 5316 Magician 线段树维护最大值的更多相关文章

  1. hdu 5316 Magician 线段树

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=5316 Magician Time Limit: 18000/9000 MS (Java/Others)  ...

  2. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  3. 线段树(维护最大值):HDU Billboard

    Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. Codeforces 777E(离散化+dp+树状数组或线段树维护最大值)

    E. Hanoi Factory time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  5. HDU 6406 Taotao Picks Apples 线段树维护

    题意:给个T,T组数据: 每组给个n,m:n个数,m个操作: (对序列的操作是,一开始假设你手上东西是-INF,到i=1时拿起1,之后遍历,遇到比手头上的数量大的数时替换(拿到手的算拿走),问最后拿走 ...

  6. hdu 5068 线段树维护矩阵乘积

    http://acm.hdu.edu.cn/showproblem.php?pid=5068 题意给的略不清晰 m个询问:从i层去j层的方法数(求连段乘积)或者修改从x层y门和x+1层z门的状态反转( ...

  7. 51nod 1376【线段树维护区间最大值】

    引自:wonter巨巨的博客 定义 dp[i] := 以数字 i(不是下标 i)为结尾的最长上升长度 然后用线段树维护 dp[i]: 每个节点维护 2 个信息,一个是当前区间的最大上升长度,一个是最大 ...

  8. HDU 6155 Subsequence Count 线段树维护矩阵

    Subsequence Count Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Oth ...

  9. hdu 4037 Development Value(线段树维护数学公式)

    Development Value Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others ...

随机推荐

  1. Java基础进阶类名整理

    类名综合 数学类: Math:数学运算 BigDecimal:用于精确计算数据 数组工具类: Arrays:数组工具类,用于对数组的操作 时间操作: JDK8以前: Date:表示一个时间,并面向对象 ...

  2. 【JS学习】for-in与for-of

    前言:本博客系列为学习后盾人js教程过程中的记录与产出,如果对你有帮助,欢迎关注,点赞,分享.不足之处也欢迎指正,作者会积极思考与改正. 总述: 名称 遍历 适用 for-in 索引 主要建议白能力对 ...

  3. docker save 保存导出镜像

    Docker保存镜像 tag 镜像 # 镜像打 tag 标签 # docker tag 镜像id/名 新名字 docker tag fce91102e17d tomcat01 commit 镜像 注意 ...

  4. 记一次centos7重启后docker无法启动的问题

    问题描述 在重新了centos7系统后,docker突然就启动不了了,查看报错信息 [root@localhost ~]# systemctl status docker.service ● dock ...

  5. Pytorch 中张量的理解

    张量是一棵树 长久以来,张量和其中维度的概念把我搞的晕头转向. 一维的张量是数组,二维的张量是矩阵,这也很有道理. 但是给一个二维张量,让我算出它每一行的和,应该用 sum(dim=0) 还是 sum ...

  6. Centos7.4 小白式安装(初学)

    虚拟机安装Centos7.4系统 适用人群(初学者) 下载Centos7.4镜像 https://pan.baidu.com/s/1NtjfdHV3OWAvfDj5vrR7HQ  提取码:hzzw 虚 ...

  7. js模仿京东首页的倒计时功能

    模仿京东首页的倒计时 我们学习了定时器,可以用定时器做一个倒计时,于是我模仿了京东首页倒计时. 先看看京东首页的倒计时. 思路: 如何倒计时? 给一个未来的时间.然后计算未来时间到现在的时间戳. 用定 ...

  8. 2021年【线上】lammps分子动力学技术实战培训班

    材料模拟分子动力学课程 3月19号--22号 远程在线课 lammps分子动力学课程 3月12号--15号 远程在线课 第一性原理VASP实战课 3月25号-28号 远程在线课 量子化学Gaussia ...

  9. 第2章_神经网络入门_2-5&2-6 数据处理与模型图构建

    目录 神经元的TF实现 安装 神经网络的TF实现 神经元的TF实现 安装 版本: Python 2.7 tf 1.8.0 Linux 略 demo 神经网络的TF实现 # py36 tf 2.1. # ...

  10. pyinstaller打包shotgun有关的程序

    By 鬼猫猫 http://www.cnblogs.com/muyr/ 背景 使用pyinstaller打包跟shotgun有关的程序后,在自己电脑上运行都OK,但是编译好的exe在其他人的电脑上运行 ...