hdu 5316 Magician 线段树维护最大值
题目链接: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 线段树维护最大值的更多相关文章
- hdu 5316 Magician 线段树
链接:http://acm.hdu.edu.cn/showproblem.php? pid=5316 Magician Time Limit: 18000/9000 MS (Java/Others) ...
- HDU.5692 Snacks ( DFS序 线段树维护最大值 )
HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...
- 线段树(维护最大值):HDU Billboard
Billboard Time Limit: 20000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- Codeforces 777E(离散化+dp+树状数组或线段树维护最大值)
E. Hanoi Factory time limit per test 1 second memory limit per test 256 megabytes input standard inp ...
- HDU 6406 Taotao Picks Apples 线段树维护
题意:给个T,T组数据: 每组给个n,m:n个数,m个操作: (对序列的操作是,一开始假设你手上东西是-INF,到i=1时拿起1,之后遍历,遇到比手头上的数量大的数时替换(拿到手的算拿走),问最后拿走 ...
- hdu 5068 线段树维护矩阵乘积
http://acm.hdu.edu.cn/showproblem.php?pid=5068 题意给的略不清晰 m个询问:从i层去j层的方法数(求连段乘积)或者修改从x层y门和x+1层z门的状态反转( ...
- 51nod 1376【线段树维护区间最大值】
引自:wonter巨巨的博客 定义 dp[i] := 以数字 i(不是下标 i)为结尾的最长上升长度 然后用线段树维护 dp[i]: 每个节点维护 2 个信息,一个是当前区间的最大上升长度,一个是最大 ...
- HDU 6155 Subsequence Count 线段树维护矩阵
Subsequence Count Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Oth ...
- hdu 4037 Development Value(线段树维护数学公式)
Development Value Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others ...
随机推荐
- linux中进制转换
方式一:使用$[]或$(()) 格式为:$[base#number]或$((base#number)),其中base为进制,number为对应进制数. 这种方式输入2进制.16进制等,但只能输出为10 ...
- VB基础总结
前段时间用VB写了一个简单窗口小应用,久了不碰VB,都忘了,下面用思维导图简单总结了一些基础的东西,方便以后快速查阅.
- Databricks 第7篇:管理Secret
有时,访问数据要求您通过JDBC对外部数据源进行身份验证,可以使用Azure Databricks Secret来存储凭据,并在notebook和job中引用它们,而不是直接在notebook中输入凭 ...
- PYTHON爬虫实战_垃圾佬闲鱼爬虫转转爬虫数据整合自用二手急速响应捡垃圾平台_3(附源码持续更新)
说明 文章首发于HURUWO的博客小站,本平台做同步备份发布. 如有浏览或访问异常图片加载失败或者相关疑问可前往原博客下评论浏览. 原文链接 PYTHON爬虫实战_垃圾佬闲鱼爬虫转转爬虫数据整合自用二 ...
- [Usaco2005 Dec]Scales 天平
题目描述 约翰有一架用来称牛的体重的天平.与之配套的是N(1≤N≤1000)个已知质量的砝码(所有砝码质量的数值都在31位二进制内).每次称牛时,他都把某头奶牛安置在天平的某一边,然后往天平另一边加砝 ...
- CSS不用背景图片实现优惠券样式反圆角,凹圆角,反向半圆角,并且背景渐变
日常开发过程中,特别是商城相关应用开发过程中,时常会遇到花里胡哨的设计图,比如优惠券样式,上图: 实现思路如下: 1.先写一个外容器,实现背景色渐变: Html: 1 <div clas ...
- libuv中实现tcp服务器
目录 1.说明 2.libuv的tcp server 3.API简介 3.1.uv_tcp_init 3.2.uv_ip4_addr 3.3.uv_tcp_bind 3.4.uv_listen 3.5 ...
- WPF权限控制——【1】界面布局
本来就不怎么喜欢写博客,好不容易申请了博客园的账号,迈出了先前没有跨越的第一步:转眼间几年的时间就过去了,还是空空如也.今天的心境是这样的,发现wpf相关的资料及源码实在不多,就想写下随笔:一方面是自 ...
- UNIX DOMAIN SOCKETS IN GO unix域套接字
Unix domain sockets in Go - Golang News https://golangnews.org/2019/02/unix-domain-sockets-in-go/ pa ...
- 逃逸分析与栈、堆分配分析 escape_analysis
小结: 1.当形参为 interface 类型时,在编译阶段编译器无法确定其具体的类型.因此会产生逃逸,最终分配到堆上. 2.The construction of a value doesn't d ...