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 }
View Code

 

posted @ 2015-07-29 16:32  星陨之泪  阅读(280)  评论(0编辑  收藏  举报