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 这个题目我开始直接暴力,然后就超时了,不知道该怎么做,直接看了题解,这个习惯其实不太好. 不过网上的思路真的很厉害,看完之后有点伤心,感觉自己应该 ...
随机推荐
- kafka启动报错Cannot allocate memory;There is insufficient memory for the Java Runtime Environment to continue.
kafka启动过程报错,配置没有问题,这就懵了!! Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000 ...
- 连接数据库+注册->登录->抽奖(有关联关系的接口)
注册账号信息需要写入数据库,登录和抽奖时从数据库获取数据 一.连接数据库 my_sql.py: import pymysql class MyDb: def __init__(self,host,pa ...
- oracle为IN OUT变量或OUT变量赋值时提示“表达式''不能用作赋值目标”
是因为IN OUT变量和OUT变量是要输出的,不能赋给它常量值,这样它就不能再被赋值而输出了,所以是禁止赋常量值的,比如''也是常量值,也不可以赋给这两种类型的变量,如果不能把存储过程中的其他变量赋给 ...
- python模块-hmac
Hmac算法:Keyed-Hashing for Message Authentication.它通过一个标准算法,在计算哈希的过程中,把key混入计算过程中. import timefrom has ...
- SDUT OJ 数据结构实验之二叉树六:哈夫曼编码
数据结构实验之二叉树六:哈夫曼编码 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descr ...
- SDUT OJ 顺序表应用1:多余元素删除之移位算法
顺序表应用1:多余元素删除之移位算法 Time Limit: 1000 ms Memory Limit: 650 KiB Submit Statistic Discuss Problem Descri ...
- jQuery 遍历 - closest() 方法
jQuery 遍历参考手册 实例 本例演示如何通过 closest() 完成事件委托.当被最接近的列表元素或其子后代元素被点击时,会切换黄色背景: $( document ).bind("c ...
- 洛谷 P1372 又是毕业季I
可能所有的数论题都是这样玄学.... 题目链接:https://www.luogu.org/problemnew/show/P1372 这道题通过暴力的枚举可以发现是不可做的(当然我也不会做) 然后就 ...
- python 获得毫秒级时间戳
import time import datetime t = time.time() print (t) #原始时间数据 print (int(t)) #秒级时间戳 print (int(round ...
- bzoj3196 二逼平衡树 树状数组套线段树
题目传送门 思路:树状数组套线段树模板题. 什么是树状数组套线段树,普通的树状数组每个点都是一个权值,而这里的树状数组每个点都是一颗权值线段树,我们用前缀差分的方法求得每个区间的各种信息, 其实关键就 ...