HDU 5316——Magician——————【线段树区间合并区间最值】
Magician
Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1613 Accepted Submission(s): 470
Magicians, sorcerers, wizards, magi, and practitioners of magic by other titles have appeared in myths, folktales, and literature throughout recorded history, with fantasy works drawing from this background.
In medieval chivalric romance, the wizard often appears as a wise old man and acts as a mentor, with Merlin from the King Arthur stories representing a prime example. Other magicians can appear as villains, hostile to the hero.

Mr. Zstu is a magician, he has many elves like dobby, each of which has a magic power (maybe negative). One day, Mr. Zstu want to test his ability of doing some magic. He made the elves stand in a straight line, from position 1 to position n, and he used two kinds of magic, Change magic and Query Magic, the first is to change an elf’s power, the second is get the maximum sum of beautiful subsequence of a given interval. A beautiful subsequence is a subsequence that all the adjacent pairs of elves in the sequence have a different parity of position. Can you do the same thing as Mr. Zstu ?
Each of the test case begins with two integers n, m represent the number of elves and the number of time that Mr. Zstu used his magic.
(n,m <= 100000)
The next line has n integers represent elves’ magic power, magic power is between -1000000000 and 1000000000.
Followed m lines, each line has three integers like
type a b describe a magic.
If type equals 0, you should output the maximum sum of beautiful subsequence of interval [a,b].(1 <= a <= b <= n)
If type equals 1, you should change the magic power of the elf at position a to b.(1 <= a <= n, 1 <= b <= 1e9)
题目大意:有t组测试数据。每组有n,m。分别表示有n个精灵,m次询问。每个精灵有个能量值(可能为负值)。询问时,1 a,b表示将a位置的精灵赋值为b。0 a,b表示查询从a位置到b位置的精灵的美丽子序列的最大和。美丽子序列为下标呈现奇偶交替出现的子序列。
解题思路:这个题目很显然是线段树的题目。唯一比较难处理的是查询区间时需要是奇偶交替的子序列和。所以我们考虑四种情况,即 奇偶、偶奇、奇奇、偶偶。偶数下标开始奇数下标结尾的最大值可以由 左儿子的偶偶+右儿子的奇奇 得到,也可以由左儿子的偶奇+右儿子偶奇得到。也可以是直接由左儿子或者右儿子的偶奇得到的。类推其他三种情况。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+20;
const int INF=0x3f3f3f3f;
typedef long long INT;
#define mid (L+R)/2
#define lson rt*2,L,mid
#define rson rt*2+1,mid+1,R
#define max(a,b) ((a)>(b)?(a):(b))
INT a[maxn];
int n;
struct SegTree{
INT oj,jo,jj,oo;
void change(){
jo=jj=oo=oj=-INF;
}
}seg[maxn*4];
void PushUpDif(SegTree &ret,SegTree <ree,SegTree &rtree){
INT jjv1,jjv2,jov1,jov2,oov1,oov2,ojv1,ojv2;
jjv1=max(ltree.jj,rtree.jj);//从左右子树得到jj的情况
jjv2=max(ltree.jj+rtree.oj,ltree.jo+rtree.jj);//需要合并左子树jj右子树oj和左子树jo右子树jj的情况
ret.jj=max(jjv1,jjv2);//取最值
//下面三种同理可得
ojv1=max(ltree.oj,rtree.oj);
ojv2=max(ltree.oo+rtree.jj,ltree.oj+rtree.oj);
ret.oj=max(ojv1,ojv2);
jov1=max(ltree.jo,rtree.jo);
jov2=max(ltree.jj+rtree.oo,ltree.jo+rtree.jo);
ret.jo=max(jov1,jov2);
oov1=max(ltree.oo,rtree.oo);
oov2=max(ltree.oj+rtree.oo,ltree.oo+rtree.jo);
ret.oo=max(oov1,oov2);
} void build(int rt,int L,int R){
seg[rt].jo=seg[rt].oj=seg[rt].jj=seg[rt].oo=-INF;
if(L==R){
if(L%2==0){
seg[rt].oo=a[L];
}else{
seg[rt].jj=a[L];
}
return ;
}
build(lson);
build(rson);
PushUpDif(seg[rt],seg[rt*2],seg[rt*2+1]);
} void update(int rt,int L,int R,INT pos,INT val){
if(L==R){
if(L%2==0){
seg[rt].oo=val;
}else{
seg[rt].jj=val;
}
return ;
}
if(pos<=mid){
update(lson,pos,val);
}else{
update(rson,pos,val);
}
PushUpDif(seg[rt],seg[rt*2],seg[rt*2+1]);
} SegTree query(int rt,int L,int R,INT l_ran,INT r_ran){
if(l_ran<=L&&R<=r_ran){
return seg[rt];
}
SegTree ret,lret,rret;
ret.change(),lret.change(),rret.change();
if(l_ran<=mid){
lret=query(lson,l_ran,r_ran);
}
if(r_ran>mid){
rret=query(rson,l_ran,r_ran);
}
PushUpDif(ret,lret,rret);
return ret;
}
int main(){
int t,m,typ;
INT aa,bb;
SegTree ans;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
build(1,1,n);
for(int i=0;i<m;i++){
scanf("%d%lld%lld",&typ,&aa,&bb);
if(typ==1){
update(1,1,n,aa,bb);
}else{
ans=query(1,1,n,aa,bb);
INT ans1=max(ans.jj,ans.oo),ans2=max(ans.jo,ans.oj);
printf("%lld\n",max(ans1,ans2));
}
}
}
return 0;
}
/*
20
10 6
1 2 3 4 5 5 6 -4 5 10 0 1 5
0 4 7
0 4 8
1 1 -1
0 1 3
0 1 4 5 3
-5 7 -3 4 5 0 1 3
1 1 0
0 1 3 */
HDU 5316——Magician——————【线段树区间合并区间最值】的更多相关文章
- hdu 5316 Magician 线段树维护最大值
题目链接:Magician 题意: 给你一个长度为n的序列v,你需要对这个序列进行m次操作,操作一共有两种,输入格式为 type a b 1.如果type==0,你就需要输出[a,b]区间内的美丽序列 ...
- hdu 5316 Magician 线段树
链接:http://acm.hdu.edu.cn/showproblem.php? pid=5316 Magician Time Limit: 18000/9000 MS (Java/Others) ...
- HDU 3308 LCIS(线段树单点更新区间合并)
LCIS Given n integers. You have two operations: U A B: replace the Ath number by B. (index counting ...
- 2015 UESTC 数据结构专题D题 秋实大哥与战争 变化版本的线段树,合并区间,单点查询
D - 秋实大哥与战争 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 D ...
- 约会安排 HDU - 4553(线段树区间查询,区间修改,区间合并)
题目: 寒假来了,又到了小明和女神们约会的季节. 小明虽为屌丝级码农,但非常活跃,女神们常常在小明网上的大段发言后热情回复“呵呵”,所以,小明的最爱就是和女神们约会.与此同时,也有很多基友找他开黑, ...
- hdu 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
- HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...
- codeforces Good bye 2016 E 线段树维护dp区间合并
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
- HDU 2665.Kth number-可持久化线段树(无修改区间第K小)模板 (POJ 2104.K-th Number 、洛谷 P3834 【模板】可持久化线段树 1(主席树)只是输入格式不一样,其他几乎都一样的)
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- J - Super Mario HDU - 4417 线段树 离线处理 区间排序
J - Super Mario HDU - 4417 这个题目我开始直接暴力,然后就超时了,不知道该怎么做,直接看了题解,这个习惯其实不太好. 不过网上的思路真的很厉害,看完之后有点伤心,感觉自己应该 ...
随机推荐
- ECS服务里或者阿里云服务器的二级域名设置方法
我们要实现的效果是,xuxinshuai.abc.com ,具体怎么实现,看下面的流程 第一步:备案域名要有,假如就是www.abc.com 第二步:网站的服务器是IIS的情况下,在部署网站时,需要设 ...
- C#中的Linq使用
First()与FirstOrDefault() 如何结合Expression 如何拼接以避免复杂的switch语句
- 数据库处理session类
<?php /* * 使用数据库处理session * php.ini 中 session.save_handler 设为 "user" */ class Dbsession ...
- 关于GNU规范的语法扩展
GNU 是一款能用于构建类 Unix 操作系统的计算机软件合集,由自由软件之父 Richard Stallman 开创,于 1983 年 9 月 27 日对外发布.GNU 完全由自由软件(free s ...
- Atcoder Grand Contest 031C(构造,思维,异或,DFS)
#include<bits/stdc++.h>using namespace std;int n,a,b,sum;void dfs(int x,int y,int ban){ if( ...
- 【Linux】DNS服务-BIND基础配置
1.BIND简介 现在使用最为广泛的DNS服务器软件是BIND(Berkeley Internet Name Domain),最早有伯克利大学的一名学生编写,现在最新的版本是9,有ISC(Intern ...
- 搭建svn管理平台
安装svn服务器:yum -y install subversion 创建svn的目录:mkdir -p /data/svn 初始化svn目录:svnadmin create /data/svn co ...
- Javascript 连接两个数组
JS合并两个数组的方法 我们在项目过程中,有时候会遇到需要将两个数组合并成为一个的情况.比如: var a = [1,2,3]; var b = [4,5,6]; 有两个数组a.b,需求是将两个数组合 ...
- samtools软件作用
samtools的说明文档:http://samtools.sourceforge.net/samtools.shtml samtools是一个用于操作sam和bam文件的工具合集,包含有许多命令.以 ...
- Linux之旅(二)
上一章讲到,mysql 安装遇到问题 ...莫名其妙好了,此处已回想不起为什么好了,只得跳过. 六.安装php7 参考教程[ http://www.thinkphp.cn/topic/48196.ht ...