标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5316
题意:给出一个大小为n的区间,2种操作,更新某一个点的值,或者查询[l,r]区间的“最大值序列”(要求该序列的下标奇偶相间)
思路:线段树的单点更新和区间合并可以实现题目要求,我们维护4个数据就好,查询的比较特殊
(1).区间里最大的以奇数开头和以奇数结尾的序列
(2).区间里最大的以偶数开头和以偶数结尾的序列
(3).区间里最大的以奇数开头和以偶数结尾的序列
(4).区间里最大的以偶数开头和以奇数结尾的序列
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define LL long long #define maxn 100030 #define inf 100000000030 #define data tree using namespace std; struct Tree { int l,r; LL eo,ee,oo,oe; }tree[maxn*5]; LL s[maxn]; void pushup(int root) { tree[root].ee=max(tree[root<<1].eo+tree[root<<1|1].ee,tree[root<<1].ee+tree[root<<1|1].oe); tree[root].ee=max(tree[root].ee,tree[root<<1].ee); tree[root].ee=max(tree[root].ee,tree[root<<1|1].ee); tree[root].oo=max(tree[root<<1].oe+tree[root<<1|1].oo,tree[root<<1].oo+tree[root<<1|1].eo); tree[root].oo=max(tree[root].oo,tree[root<<1].oo); tree[root].oo=max(tree[root].oo,tree[root<<1|1].oo); tree[root].eo=max(tree[root<<1].eo+tree[root<<1|1].eo,tree[root<<1].ee+tree[root<<1|1].oo); tree[root].eo=max(tree[root].eo,tree[root<<1].eo); tree[root].eo=max(tree[root].eo,tree[root<<1|1].eo); tree[root].oe=max(tree[root<<1].oe+tree[root<<1|1].oe,tree[root<<1].oo+tree[root<<1|1].ee); tree[root].oe=max(tree[root].oe,tree[root<<1].oe); tree[root].oe=max(tree[root].oe,tree[root<<1|1].oe); } void build(int root,int l,int r) { tree[root].l=l; tree[root].r=r; if (tree[root].l==tree[root].r) { if (l%2==0) tree[root].oo=s[l]; else tree[root].ee=s[l]; return; } int mid=(l+r)>>1; build(root<<1,l,mid); build(root<<1|1,mid+1,r); pushup(root); } void update(int root,int p,int val) { if (tree[root].l==tree[root].r) { if (tree[root].l%2==0) tree[root].oo=val; else tree[root].ee=val; return; } int mid=(tree[root].l+tree[root].r)>>1; if (mid>=p) update(root<<1,p,val); else if (mid<p) update(root<<1|1,p,val); pushup(root); } Tree query(int root,int l,int r) { //cout<<root<<endl; if (tree[root].l==l && tree[root].r==r) { return tree[root]; } int mid=(tree[root].l+tree[root].r)>>1; if (mid>=r) return query(root<<1,l,r); else if (mid<l) return query(root<<1|1,l,r); else { Tree tmp1=query(root<<1,l,mid); Tree tmp2=query(root<<1|1,mid+1,r); Tree tmp3; tmp3.ee=max(tmp1.eo+tmp2.ee,tmp1.ee+tmp2.oe); tmp3.ee=max(tmp3.ee,tmp1.ee); tmp3.ee=max(tmp3.ee,tmp2.ee); tmp3.oo=max(tmp1.oe+tmp2.oo,tmp1.oo+tmp2.eo); tmp3.oo=max(tmp3.oo,tmp1.oo); tmp3.oo=max(tmp3.oo,tmp2.oo); tmp3.eo=max(tmp1.eo+tmp2.eo,tmp1.ee+tmp2.oo); tmp3.eo=max(tmp3.eo,tmp1.eo); tmp3.eo=max(tmp3.eo,tmp2.eo); tmp3.oe=max(tmp1.oe+tmp2.oe,tmp1.oo+tmp2.ee); tmp3.oe=max(tmp3.oe,tmp1.oe); tmp3.oe=max(tmp3.oe,tmp2.oe); return tmp3; } } int main() { int t,n,m; scanf("%d",&t); while (t--) { memset(tree,-inf,sizeof(tree)); scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%I64d",&s[i]); build(1,1,n); for (int i=0;i<m;i++) { int k,a,b; scanf("%d",&k); if (k==1) { scanf("%d%d",&a,&b); update(1,a,b); } else { LL res=-inf; scanf("%d%d",&a,&b); Tree tmp=query(1,a,b); res=max(res,tmp.oo); res=max(res,tmp.oe); res=max(res,tmp.ee); res=max(res,tmp.eo); printf("%I64d\n",res); } } } }
标签:
原文地址:http://blog.csdn.net/csdn364988181/article/details/51366401