hdu 5316 Magician(2015多校第三场第1题)线段树单点更新+区间合并
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5316
题意:给你n个点,m个操作,每次操作有3个整数t,a,b,t表示操作类型,当t=1时讲a点的值改成b;当t=0时,查询区间a,b之间最大的子序列和,这个子序列中的相邻的元素的原来的下标奇偶性都不同。
思路:这道题难点就在查询,其余都是模板,而根据查询,你只要分别把下一个区间的奇偶最大的情况分别比较,合并到上一个区间这样可以构建一个每个节点存有区间中奇开头偶开头,奇结尾,偶结尾这些区间情况的树。
代码:
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <iostream> 5 #include <algorithm> 6 #include <vector> 7 8 #define N 100005 9 #define LL __int64 10 #define INF 0x3f3f3f3f 11 using namespace std; 12 #define ls rt<<1 13 #define rs rt<<1|1 14 #define lson l,m,rt<<1 15 #define rson m+1,r,rt<<1|1 16 17 struct node 18 { 19 int l,r; 20 LL jo,oo,oj,jj; 21 }seg[N<<4],aa; 22 LL ans; 23 void Push_Up(int rt) 24 { 25 seg[rt].jj=max(max(seg[ls].jj+seg[rs].oj,seg[ls].jo+seg[rs].jj),max(seg[ls].jj,seg[rs].jj)); 26 seg[rt].oo=max(max(seg[ls].oo+seg[rs].jo,seg[ls].oj+seg[rs].oo),max(seg[ls].oo,seg[rs].oo)); 27 seg[rt].jo=max(max(seg[ls].jj+seg[rs].oo,seg[ls].jo+seg[rs].jo),max(seg[ls].jo,seg[rs].jo)); 28 seg[rt].oj=max(max(seg[ls].oo+seg[rs].jj,seg[ls].oj+seg[rs].oj),max(seg[ls].oj,seg[rs].oj)); 29 } 30 31 void Build(int l,int r,int rt) 32 { 33 seg[rt].l=l; 34 seg[rt].r=r; 35 if(l==r) 36 { 37 LL a; 38 scanf("%I64d",&a); 39 if(l&1) 40 { 41 seg[rt].jj=a; 42 seg[rt].oo=-INF; 43 } 44 else 45 { 46 seg[rt].oo=a; 47 seg[rt].jj=-INF; 48 } 49 seg[rt].jo=seg[rt].oj=-INF; 50 return ; 51 } 52 int m=(l+r)>>1; 53 Build(lson); 54 Build(rson); 55 Push_Up(rt); 56 } 57 58 void Update(int p,int x,int rt) 59 { 60 if(seg[rt].l==seg[rt].r&&seg[rt].l==p) 61 { 62 if(p&1) 63 seg[rt].jj=x; 64 else 65 seg[rt].oo=x; 66 return ; 67 } 68 int m=(seg[rt].l+seg[rt].r)>>1; 69 if(p<=m) 70 Update(p,x,ls); 71 else 72 Update(p,x,rs); 73 Push_Up(rt); 74 } 75 76 void Get(node ll,node rr) 77 { 78 aa.jj=max(max(ll.jj+rr.oj,ll.jo+rr.jj),max(ll.jj,rr.jj)); 79 aa.oo=max(max(ll.oo+rr.jo,ll.oj+rr.oo),max(ll.oo,rr.oo)); 80 aa.jo=max(max(ll.jj+rr.oo,ll.jo+rr.jo),max(ll.jo,rr.jo)); 81 aa.oj=max(max(ll.oo+rr.jj,ll.oj+rr.oj),max(ll.oj,rr.oj)); 82 } 83 84 node Query(int l,int r,int rt) 85 { 86 if(seg[rt].l==l&&seg[rt].r==r) 87 { 88 aa=seg[rt]; 89 ans=max(max(aa.jj,aa.jo),max(aa.oj,aa.oo)); 90 return seg[rt]; 91 } 92 int m=(seg[rt].l+seg[rt].r)>>1; 93 ans=0; 94 if(r<=m) 95 aa=Query(l,r,ls); 96 else if(l>m) 97 aa=Query(l,r,rs); 98 else 99 { 100 node ll,rr; 101 ll=Query(lson); 102 rr=Query(rson); 103 Get(ll,rr); 104 } 105 ans=max(max(aa.jj,aa.jo),max(aa.oj,aa.oo)); 106 return aa; 107 } 108 109 int main() 110 { 111 int n,m,a,b,t,T; 112 while(scanf("%d",&T)==1) 113 { 114 while(T--) 115 { 116 scanf("%d%d",&n,&m); 117 Build(1,n,1); 118 while(m--) 119 { 120 scanf("%d%d%d",&t,&a,&b); 121 if(t==1) 122 Update(a,b,1); 123 else 124 { 125 Query(a,b,1); 126 printf("%I64d\n",ans); 127 } 128 } 129 } 130 } 131 return 0; 132 }