题目链接:
题目描述:
有n个精灵,每个精灵都有一个魔法值,现在有两个操作:
(0, a, b)查询[a, b]序列中的一个完美序列的最大和,完美序列就是数组中相邻数字的下标奇偶性不同。
(1, a, b)更新下标为a的精灵魔法值为b。
对的,没错就是这个意思,但是比赛的时候就是题意卡的死死的有没有啊,就是各种不懂有没有啊!!!
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 typedef long long LL; 7 #define Max(a, b, c, d) max(max(a, b), max(c, d)) 8 const LL INF = 1000000000; 9 const LL maxn = 400000; 10 struct point 11 { 12 LL odd_e, odd_o, even_o, even_e; 13 LL Maxn () 14 { 15 return Max(odd_e, odd_o, even_e, even_o); 16 } 17 }; 18 struct node 19 { 20 LL l, r; 21 point p; 22 LL Mid () 23 { 24 return (l+r)/2; 25 } 26 } tree[maxn]; 27 point Add (point x, point y) 28 { 29 point s; 30 s.even_e = Max(x.even_e, y.even_e, x.even_e+y.odd_e, x.even_o+y.even_e); 31 s.even_o = Max(x.even_o, y.even_o, x.even_e+y.odd_o, x.even_o+y.even_o); 32 s.odd_e = Max(x.odd_e, y.odd_e, x.odd_e +y.odd_e, x.odd_o+y.even_e); 33 s.odd_o = Max(x.odd_o, y.odd_o, x.odd_o +y.even_o, x.odd_e+y.odd_o); 34 return s; 35 } 36 void bulid (LL root, LL l, LL r) 37 { 38 tree[root].l = l; 39 tree[root].r = r; 40 41 if (l == r) 42 { 43 tree[root].p.even_e = -INF; 44 tree[root].p.even_o = -INF; 45 tree[root].p.odd_e = -INF; 46 tree[root].p.odd_o = -INF; 47 LL num; 48 scanf ("%lld", &num); 49 if (l%2) 50 tree[root].p.odd_o = num; 51 else 52 tree[root].p.even_e = num; 53 return ; 54 } 55 bulid (2*root+1, l, tree[root].Mid()); 56 bulid (2*root+2, tree[root].Mid()+1, r); 57 tree[root].p = Add (tree[2*root+1].p, tree[2*root+2].p); 58 } 59 void update (LL root, LL x, LL y) 60 { 61 if (tree[root].l == tree[root].r) 62 { 63 tree[root].p.even_e = -INF; 64 tree[root].p.even_o = -INF; 65 tree[root].p.odd_e = -INF; 66 tree[root].p.odd_o = -INF; 67 if ( x%2 == 0 ) 68 tree[root].p.even_e = y; 69 else 70 tree[root].p.odd_o = y; 71 return ; 72 } 73 if (x <= tree[root].Mid()) 74 update(2*root+1, x, y); 75 else 76 update(2*root+2, x, y); 77 tree[root].p = Add (tree[2*root+1].p, tree[2*root+2].p); 78 } 79 point query (LL root, LL l, LL r) 80 { 81 if (tree[root].l == l && tree[root].r == r) 82 return tree[root].p; 83 if (r <= tree[root].Mid()) 84 query (2*root+1, l, r); 85 else if (tree[root].Mid() < l) 86 query (2*root+2, l, r); 87 else 88 { 89 point ls, rs; 90 ls = query (2*root+1, l, tree[root].Mid()); 91 rs = query (2*root+2, tree[root].Mid()+1, r); 92 return Add (ls, rs); 93 } 94 } 95 int main () 96 { 97 LL t; 98 scanf ("%lld", &t); 99 100 while (t --) 101 { 102 LL n, q; 103 scanf ("%lld %lld", &n, &q); 104 bulid(0, 1, n); 105 while (q --) 106 { 107 LL type, a, b; 108 scanf ("%lld %lld %lld", &type, &a, &b); 109 if (type == 0) 110 { 111 point s = query (0, a, b); 112 printf ("%lld ", s.Maxn()); 113 } 114 else 115 update (0, a, b); 116 } 117 } 118 return 0; 119 }