一開始度错题了,题意是求一段和最大的【子序列】,要求相邻两个元素的位置必须互为奇偶。

这样我们能够使用线段树维护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(线段树)的更多相关文章

  1. hdu 5316 Magician 线段树

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

  2. hdu 5316 Magician 线段树维护最大值

    题目链接:Magician 题意: 给你一个长度为n的序列v,你需要对这个序列进行m次操作,操作一共有两种,输入格式为 type a b 1.如果type==0,你就需要输出[a,b]区间内的美丽序列 ...

  3. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  4. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  5. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  6. HDU 5316——Magician——————【线段树区间合并区间最值】

    Magician Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  7. HDU 5316 Magician (线段树,单值修改,微变形)

    题意:给一个初始序列A[1,n],第j个数字代表精灵j的power值,有两种操作:(1)查询区间[L,R] (2)修改某个精灵的power值. 但,查询的是区间[L,R]中一个美丽子序列sub[l,r ...

  8. HDU 5877 dfs+ 线段树(或+树状树组)

    1.HDU 5877  Weak Pair 2.总结:有多种做法,这里写了dfs+线段树(或+树状树组),还可用主席树或平衡树,但还不会这两个 3.思路:利用dfs遍历子节点,同时对于每个子节点au, ...

  9. HDU 3308 LCIS (线段树区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...

  10. HDU 2795 Billboard (线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 题目大意:有一块h*w的矩形广告板,要往上面贴广告;   然后给n个1*wi的广告,要求把广告贴 ...

随机推荐

  1. 51nod 1007 正整数分组【01背包变形】

    1007 正整数分组 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 ...

  2. springboot的配置文件

    一.springboot配置文件值的注入 @ConfigurationProperties(prefix = "xxx") 实例代码: @Component @Configurat ...

  3. 牛客网暑期ACM多校训练营(第一场) - J Different Integers(线段数组or莫队)

    链接:https://www.nowcoder.com/acm/contest/139/J来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 524288K,其他语言1048 ...

  4. 洛谷——P1755 斐波那契的拆分

    P1755 斐波那契的拆分 题目背景 无 题目描述 已知任意一个正整数都可以拆分为若干个斐波纳契数,现在,让你求出n的拆分方法 输入输出格式 输入格式: 一个数t,表示有t组数据 接下来t行,每行一个 ...

  5. Flip Game -- LeetCode

    You are playing the following Flip Game with your friend: Given a string that contains only these tw ...

  6. SPOJ705 SUBST1 - New Distinct Substrings(后缀数组)

    给一个字符串求有多少个不相同子串. 每一个子串一定都是某一个后缀的前缀.由此可以推断出总共有(1+n)*n/2个子串,那么下面的任务就是找这些子串中重复的子串. 在后缀数组中后缀都是排完序的,从sa[ ...

  7. SQL表操作习题5 26~35题

  8. 解魔方的机器人攻略13 – 安装Lejos(上)

    由 动力老男孩 发表于 2009/12/27 16:58:23 Firmware(固件)相当于是机器人的操作系统,乐高NXT出厂时已经内置了一套Firmware,并且配备了非常强大的LabVIEW开发 ...

  9. Windows 8.1中WinRT的变化(一)——新增控件

    这次WinRT的变化还是不小的,就拿新增控件来说,就有如下几种: AppBar 控件 我以前写过一篇文章接受过如何在WinRT程序中快速创建Metro风格图标,现在MS已经把他们标准化了,就不用我们自 ...

  10. 《Flex 第一步》

    //什么是FlexFlex 是一个针对企业级富互联网应用的表示层解决方案.具体地说,Flex是一种应用程序框架.富互联网应用程序,Rich Internet Application,简称RIA,将桌面 ...