HDU 5316 Magician(线段树 区间合并)
来源:互联网 发布:5g网络有多快 编辑:程序博客网 时间:2024/04/29 18:08
题意:给你n(n<=10^5)个数ai(-10^9<=ai<=10^9)。要求从这里面取出它的序列,这些序列满足下标奇偶相间,求某段区间的这种序列的最大和值。
分析:最初没读懂题意。。。。 一看数据范围和查询方式,肯定和线段树相关,问题的要求又有点像DP。分析知道,其实就是求线段树的区间合并问题,取出的序列只可能是以奇数开头奇数结尾,奇数开头偶数结尾,偶数开头偶数结尾,偶数开头奇数结尾。用jj,jo,oo,oj表示。当合并的适合考虑这四种情况就是可以了。
jj=max(l.jj ,r.jj, l.jj+r.oj, l.jo+r.jo);其他依次类推
#include <iostream>#include <stdio.h>#include <math.h>#include <algorithm>#include <queue>#include <stack>#include <vector>#include <string>#include <string.h>#include <map>#include <set>using namespace std;#define maxn 200005#define inff 0x7FFFFFFFFFFFFFFFtypedef __int64 LL;LL a[maxn];int n,m; LL max(LL x,LL y){ return x>y?x:y;} LL max(LL x,LL y,LL z,LL w){ return max(max(x,y),max(z,w));}struct node{ int l,r; LL oo,jj,jo,oj;}tr[maxn<<2];inline LL add(LL x,LL y){ if(x==-inff||y==-inff)return -inff; else return x+y;}void pushup(int id){ tr[id].jj=max(add(tr[id*2].jo,tr[id*2+1].jj),add(tr[id*2].jj,tr[id*2+1].oj),tr[id*2].jj,tr[id*2+1].jj); tr[id].oo=max(add(tr[id*2].oj,tr[id*2+1].oo),add(tr[id*2].oo,tr[id*2+1].jo),tr[id*2].oo,tr[id*2+1].oo); tr[id].jo=max(add(tr[id*2].jj,tr[id*2+1].oo),add(tr[id*2].jo,tr[id*2+1].jo),tr[id*2].jo,tr[id*2+1].jo); tr[id].oj=max(add(tr[id*2].oo,tr[id*2+1].jj),add(tr[id*2].oj,tr[id*2+1].oj),tr[id*2].oj,tr[id*2+1].oj);}void build(int id,int l,int r){ tr[id].l=l; tr[id].r=r; tr[id].jj=tr[id].oo=-inff; tr[id].oj=tr[id].jo=-inff; if(l==r) { if(l%2!=0) { tr[id].jj=a[l]; tr[id].oo=tr[id].jo=tr[id].oj=-inff; } else { tr[id].oo=a[l]; tr[id].jj=tr[id].jo=tr[id].oj=-inff; } } else { int mid=(l+r)/2; build(id*2,l,mid); build(id*2+1,mid+1,r); pushup(id); }}void update(int id,int pos,LL val){ if(tr[id].l==tr[id].r) { if(tr[id].l%2!=0) { tr[id].jj=val; tr[id].oo=tr[id].jo=tr[id].oj=-inff; } else { tr[id].oo=val; tr[id].jj=tr[id].jo=tr[id].oj=-inff; } } else { int mid=(tr[id].l+tr[id].r)/2; if(pos<=mid)update(id*2,pos,val); else update(id*2+1,pos,val); pushup(id); }}node query(int id,int l,int r){ if(l<=tr[id].l&&tr[id].r<=r) { return tr[id]; } else { int mid=(tr[id].l+tr[id].r)/2; if(r<=mid)return query(id*2,l,r); else if(l>mid)return query(id*2+1,l,r); else { node a=query(id*2,l,r); node b=query(id*2+1,l,r); node c; c.jj=max(a.jj,b.jj,add(a.jo,b.jj),add(a.jj,b.oj)); c.oo=max(a.oo,b.oo,add(a.oj,b.oo),add(a.oo,b.jo)); c.jo=max(a.jo,b.jo,add(a.jj,b.oo),add(a.jo,b.jo)); c.oj=max(a.oj,b.oj,add(a.oo,b.jj),add(a.oj,b.oj)); return c; } }}int main(){ int t,i; //cout<<inff<<endl; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { scanf("%I64d",&a[i]); } build(1,1,n); //cout<<tr[1].jj<<" "<<tr[1].oo<<" "<<tr[1].oj<<endl; for(i=1;i<=m;i++) { int pos; LL val; int c,l,r; scanf("%d",&c); if(c==1) { scanf("%d%I64d",&pos,&val); update(1,pos,val); } else { scanf("%d%d",&l,&r); node ans=query(1,l,r); printf("%I64d\n",max(ans.jj,ans.jo,ans.oo,ans.oj)); } } } return 0;}
0 0
- HDU 5316 Magician(线段树区间合并)
- HDU 5316 Magician(线段树区间合并入门)
- hdu 5316 Magician(线段树区间合并)
- HDU 5316 Magician(线段树 区间合并)
- Hdu 5316 Magician (线段树区间合并)
- [HDU 5316] Magician (线段树+单点更新+区间询问+区间合并)
- HDU5316 Magician (线段树区间合并)
- hdu 5316 Magician(2015多校第三场第1题)线段树单点更新+区间合并
- 多校第三场 1001 hdu 5316 Magician( 区间合并线段树)
- HDU 5316 Magician(线段树区间合并, 子序列最值 多校2015啊)
- HDU5316 Magician 线段树区间合并
- hdu5316 Magician(线段树区间合并)
- hdu5316 Magician(线段树区间合并)
- HDU 5316 Magician(线段树)
- hdu 5316 Magician(线段树)
- HDU 5316 Magician(线段树)
- hdu 5316 Magician (线段树)
- 【HDU 5316】Magician(线段树)
- SAP固定资产期初导入检查
- 【C++基础之一】C++ 虚函数表解析
- k780数据解析测试
- uva 10474
- 时光切片—我是海康人
- HDU 5316 Magician(线段树 区间合并)
- springmvc 注解的适配器和映射器的配置
- python读写配置文件
- 常用模板总结(持续更新)
- iOS开发 - App程序启动原理
- UVA 10905 Children's Game
- GridView实现类似listview中divider分割线
- Python list 操作
- Python中dict详解