【HDU 5316】Magician(线段树)
一開始度错题了,题意是求一段和最大的【子序列】,要求相邻两个元素的位置必须互为奇偶。
这样我们能够使用线段树维护4个值:
一段区间内开头结尾元素为:
奇奇
奇偶
偶奇
偶偶
的最大值
之后在pushup的的时候依据题目所给的意思进行合并。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson (pos<<1)
#define rson (pos<<1|1)
typedef long long LL;
const int maxn = 100005;
const LL INF = 9999999999999999LL;
int n,m;
struct Node{
LL oe;
LL oo;
LL ee;
LL eo;
}node[maxn << 2];
LL value[maxn];
Node pushnode(Node p,Node q){
Node newNode;
newNode.oe = max(max(p.oe,q.oe),max(p.oo + q.ee,p.oe + q.oe));
newNode.oo = max(max(p.oo,q.oo),max(p.oo + q.eo,p.oe + q.oo));
newNode.ee = max(max(p.ee,q.ee),max(p.eo + q.ee,p.ee + q.oe));
newNode.eo = max(max(p.eo,q.eo),max(p.eo + q.eo,p.ee + q.oo));
return newNode;
}
void pushup(int pos){
node[pos].oe = max(max(node[lson].oe,node[rson].oe),max(node[lson].oo + node[rson].ee,node[lson].oe + node[rson].oe));
node[pos].oo = max(max(node[lson].oo,node[rson].oo),max(node[lson].oo + node[rson].eo,node[lson].oe + node[rson].oo));
node[pos].ee = max(max(node[lson].ee,node[rson].ee),max(node[lson].eo + node[rson].ee,node[lson].ee + node[rson].oe));
node[pos].eo = max(max(node[lson].eo,node[rson].eo),max(node[lson].eo + node[rson].eo,node[lson].ee + node[rson].oo));
}
void build(int l,int r,int pos){
if(l == r){
if(l & 1){
node[pos].oe = node[pos].ee = node[pos].eo = -INF;
node[pos].oo = value[l];
}
else{
node[pos].oe = node[pos].oo = node[pos].eo = -INF;
node[pos].ee = value[l];
}
return;
}
int mid = (l + r) >> 1;
build(l,mid,lson);
build(mid + 1,r,rson);
pushup(pos);
}
void update(int l,int r,int pos,int to,int v){
if(l == r){
if(l & 1){
node[pos].oe = node[pos].ee = node[pos].eo = -INF;
node[pos].oo = v;
}
else{
node[pos].oe = node[pos].oo = node[pos].eo = -INF;
node[pos].ee = v;
}
return;
}
int mid = (l + r) >> 1;
if(to <= mid)
update(l,mid,lson,to,v);
else
update(mid + 1,r,rson,to,v);
pushup(pos);
}
Node query(int l,int r,int L,int R,int pos){
if(L <= l && r <= R){
return node[pos];
}
int mid = (l + r) >> 1;
if(R <= mid)
return query(l,mid,L,R,lson);
else if(L > mid)
return query(mid + 1,r,L,R,rson);
else{
Node v1 = query(l,mid,L,R,lson);
Node v2 = query(mid + 1,r,L,R,rson);
return pushnode(v1,v2);
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++){
scanf("%I64d",&value[i]);
}
build(1,n,1);
for(int i = 0; i < m; i++){
int op;
LL a,b;
scanf("%d%I64d%I64d",&op,&a,&b);
if(op == 0){
Node nans = query(1,n,a,b,1);
LL ans = max(max(nans.oo,nans.eo),max(nans.ee,nans.oe));
printf("%I64d\n",ans);
}
else if(op == 1)
update(1,n,1,a,b);
}
}
return 0;
}
【HDU 5316】Magician(线段树)的更多相关文章
- hdu 5316 Magician 线段树
链接:http://acm.hdu.edu.cn/showproblem.php? pid=5316 Magician Time Limit: 18000/9000 MS (Java/Others) ...
- hdu 5316 Magician 线段树维护最大值
题目链接:Magician 题意: 给你一个长度为n的序列v,你需要对这个序列进行m次操作,操作一共有两种,输入格式为 type a b 1.如果type==0,你就需要输出[a,b]区间内的美丽序列 ...
- hdu 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
- hdu 4288 离线线段树+间隔求和
Coder Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- hdu 3016 dp+线段树
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- HDU 5316——Magician——————【线段树区间合并区间最值】
Magician Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- HDU 5316 Magician (线段树,单值修改,微变形)
题意:给一个初始序列A[1,n],第j个数字代表精灵j的power值,有两种操作:(1)查询区间[L,R] (2)修改某个精灵的power值. 但,查询的是区间[L,R]中一个美丽子序列sub[l,r ...
- HDU 5877 dfs+ 线段树(或+树状树组)
1.HDU 5877 Weak Pair 2.总结:有多种做法,这里写了dfs+线段树(或+树状树组),还可用主席树或平衡树,但还不会这两个 3.思路:利用dfs遍历子节点,同时对于每个子节点au, ...
- HDU 3308 LCIS (线段树区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...
- HDU 2795 Billboard (线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 题目大意:有一块h*w的矩形广告板,要往上面贴广告; 然后给n个1*wi的广告,要求把广告贴 ...
随机推荐
- Ubuntu 14.04 LTS+SublimeText3+中文输入
文本编辑器,我习惯用Sublime Text,因为很好用啊,至于那些大神们说的Vim, Emacs,我目前还用不上:Vim偶尔会用到,gedit也会常用到,emacs几乎没用过,也不会: 一.安装: ...
- CF985B Switches and Lamps【矩阵操作/枚举】
[链接]CF985B [题意]:给n盏灯,m个开关,每次按开关只能将灯从灯灭的状态转变为灯亮,问是否存在不按所有开关就将所有灯打开的方法. [分析]:有两种办法,一种代码复杂点,容易想到枚举去掉每一行 ...
- 51nod 1090 3个数和为0【二分】
1090 3个数和为0 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注 给出一个长度为N的无序数组,数组中的元素为整数,有正有负包括0,并互不相等.从 ...
- 大数据技术之_16_Scala学习_09_函数式编程-高级
第十三章 函数式编程-高级13.1 偏函数(partial function)13.1.1 提出一个需求,引出思考13.1.2 解决方式-filter + map 返回新的集合13.1.3 解决方式- ...
- [BZOJ 3108] 图的逆变换
Link: BZOJ 3108 传送门 Solution: 样例教你做题系列 观察第三个输出为No的样例,发现只要存在$edge(i,k),edge(j,k)$,那么$i,j$的出边一定要全部相同 于 ...
- PL/SQL分支、循环语句
CREATE OR REPLACE PROCEDURE PR_TEST2 IS V_CASE NUMBER(5) := 100; BEGIN IF 2 < 1 THEN DBMS_OUTPUT. ...
- GIF工具 | 分享几个Gif相关工具
文章目录 LICEcap GiFResizer LICEcap LICEcap 是一款屏幕录制工具,支持导出GIF动画图片格式,轻量级.使用简单,录制过程中可以随意改变录屏范围. 下载地址: 官方地址 ...
- JavaEE目录
第一章: Spring介绍 Spring项目搭建 Spring概念 第二章: Sprin配置详解 属性注入(构造方法注入,设值注入) 实例化(构造器(空参构造器),静态工厂,工厂方法) 装配(xml方 ...
- 警告Conversion specifies type'int' but the argument has type'size_t'
代码: #import<Foundation/Foundation.h> int main(int argc,const char * argv[]){ const char *words ...
- intellij idea 分屏设置 与快捷键
1.找到分屏功能 File -> setting -> keymap,搜索(注意大小写): Split Vertically 水平分屏 Split Horizontally 垂直分 ...