[关闭]
@tenlee 2015-07-29T08:43:49.000000Z 字数 2552 阅读 1498

HDU 5316 Magician(2015多校联合)

HDUOJ


题目链接:戳我

题目大意:

一段序列 n个数(n<=105),这 n个数的范围是109<=ai<=109,有两种操作, 0 L R代表 L R 这个区间 beautiful subsequence 的最大和。 1 a b代表修改 a位置的数为b
beautiful subsequence 的意思是下标奇偶相互交错的序列
例如 {4,7,9,2} 这个序列,beautiful subsequence
{4} {7} {9} {2}
{4,7} {7,9} {9,2} {4,2}
{4,7,9} {7,9,2}
{4,7,9,2}

解题思路:

j代表奇数,o代表偶数
奇偶交错的序列有 4 种情况。开始和结尾 分别为 jj,jo,oo,oj
故线段树内维护这四种情况的最大值即可。
更新即为普通的更新。

代码

  1. //Author LJH
  2. //www.cnblogs.com/tenlee
  3. #include <cstdio>
  4. #include <cstdlib>
  5. #include <cstring>
  6. #include <cctype>
  7. #include <cmath>
  8. #include <algorithm>
  9. #include <vector>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #define clc(a, b) memset(a, b, sizeof(a))
  14. using namespace std;
  15. typedef long long ll;
  16. const ll inf = -10000000000;
  17. const int INF = 0x3f3f3f3f;
  18. const int maxn = 1e5+5;
  19. struct Sum
  20. {
  21. ll jo, jj, oo, oj;
  22. };
  23. struct Tree
  24. {
  25. int l, r;
  26. Sum s;
  27. }tree[maxn << 2];
  28. int n, m;
  29. ll a[maxn];
  30. inline Sum getSum(Sum l, Sum r)
  31. {
  32. Sum ss;
  33. ss.jj = max(l.jj, r.jj);
  34. ss.jj = max(ss.jj, l.jj+r.oj);
  35. ss.jj = max(ss.jj, l.jo+r.jj);
  36. ss.jo = max(l.jo, r.jo);
  37. ss.jo = max(ss.jo, l.jj+r.oo);
  38. ss.jo = max(ss.jo, l.jo+r.jo);
  39. ss.oo = max(l.oo, r.oo);
  40. ss.oo = max(ss.oo, l.oj+r.oo);
  41. ss.oo = max(ss.oo, l.oo+r.jo);
  42. ss.oj = max(l.oj, r.oj);
  43. ss.oj = max(ss.oj, l.oj+r.oj);
  44. ss.oj = max(ss.oj, l.oo+r.jj);
  45. return ss;
  46. }
  47. void Build(int i, int l, int r)
  48. {
  49. tree[i].l = l;
  50. tree[i].r = r;
  51. if(l == r)
  52. {
  53. if(l%2) // j
  54. {
  55. tree[i].s.jj = a[l]; tree[i].s.jo = inf; //因为存在负数,故要初始化为负无穷
  56. tree[i].s.oo = inf; tree[i].s.oj = inf;
  57. }
  58. else
  59. {
  60. tree[i].s.jj = inf; tree[i].s.jo = inf;
  61. tree[i].s.oo = a[l]; tree[i].s.oj = inf;
  62. }
  63. return;
  64. }
  65. int mid = (l + r) >> 1;
  66. Build(i<<1, l, mid);
  67. Build(i<<1|1, mid+1, r);
  68. tree[i].s = getSum(tree[i<<1].s, tree[i<<1|1].s);
  69. }
  70. void Update(int i, int id, ll val)
  71. {
  72. if(tree[i].l == id && tree[i].r == id)
  73. {
  74. if(id%2) // 奇
  75. {
  76. tree[i].s.jj = val; tree[i].s.jo = inf;
  77. tree[i].s.oo = inf; tree[i].s.oj = inf;
  78. }
  79. else // 偶
  80. {
  81. tree[i].s.jj = inf; tree[i].s.jo = inf;
  82. tree[i].s.oo = val; tree[i].s.oj = inf;
  83. }
  84. return;
  85. }
  86. int mid = (tree[i].l + tree[i].r) >> 1;
  87. if(id > mid) Update(i<<1|1, id, val);
  88. else Update(i<<1, id, val);
  89. tree[i].s = getSum(tree[i<<1].s, tree[i<<1|1].s);
  90. }
  91. Sum Quary(int i, int l, int r)
  92. {
  93. if(tree[i].l == l && tree[i].r == r)
  94. {
  95. return tree[i].s;
  96. }
  97. int mid = (tree[i].l + tree[i].r) >> 1;
  98. if(r <= mid) return Quary(i<<1, l, r);
  99. else if(l > mid) return Quary(i<<1|1, l, r);
  100. else return(getSum(Quary(i<<1, l, mid), Quary(i<<1|1, mid+1, r)));
  101. }
  102. int main()
  103. {
  104. int T, x, y, op;
  105. Sum s;
  106. ll sum = 0, v;
  107. scanf("%d", &T);
  108. while(T--)
  109. {
  110. scanf("%d %d", &n, &m);
  111. for(int i = 1; i <= n; i++)
  112. {
  113. scanf("%lld", &a[i]);
  114. }
  115. Build(1, 1, n);
  116. while(m--)
  117. {
  118. scanf("%d", &op);
  119. if(x > y) swap(x, y);
  120. if(op == 0)
  121. {
  122. scanf("%d %d",&x, &y);
  123. if(n == 0)
  124. {
  125. puts("0");continue;
  126. }
  127. s = Quary(1, x, y);
  128. sum = max(s.jj, s.jo);
  129. sum = max(sum, s.oo);
  130. sum = max(sum, s.oj);
  131. printf("%lld\n", sum);
  132. }
  133. else
  134. {
  135. scanf("%d %lld", &x, &v);
  136. Update(1, x, v);
  137. }
  138. }
  139. }
  140. return 0;
  141. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注