CF 515E, 线段树

题目大意:在一个环形上有n棵树,其中我们要在一段可行弧上找一个最大运动距离。运动距离是这样算的,我们在可行弧上找任意两棵不同的树,然后运动距离为两棵树的高和他们的距离。

解:裸线段树,可以观察运动距离等于 dist[j] - dist[i] + h[i] + h[j], 有max((dist[j] + h[j]) + (h[i] - dist[i]),线段树搞一下即可。

 

  1 #include <cstdio>
  2 #include <string>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <cstring>
  7 #include <complex>
  8 #include <set>
  9 #include <vector>
 10 #include <map>
 11 #include <queue>
 12 #include <deque>
 13 #include <ctime>
 14 
 15 using namespace std;
 16 
 17 const double EPS = 1e-8;
 18 
 19 #define ABS(x) ((x)<0?(-(x)):(x))
 20 #define SQR(x) ((x)*(x))
 21 #define MIN(a,b) ((a)<(b)?(a):(b))
 22 #define MAX(a,b) ((a)>(b)?(a):(b))
 23 
 24 #define LSON(x) ((x)<<1)
 25 #define RSON(x) (((x)<<1)+1)
 26 #define LOWBIT(x) ((x)&(-(x)))
 27 #define MAXS 1111
 28 #define MAXN 222222
 29 #define VOIDPOINT 0
 30 #define LL long long
 31 #define OO 214748364
 32 #define INF 0x3f3f3f3f
 33 #define MP(x,y) make_pair(x,y)
 34 
 35 int d[MAXN], n, m;
 36 LL dist[MAXN], h[MAXN]; 
 37 
 38 struct SegmentTree{
 39     int l[MAXN*4], r[MAXN*4], mid[MAXN*4];
 40     LL maxx[MAXN*4], lmax[MAXN*4], rmax[MAXN*4];
 41     int gx, gy, gz;
 42     void build(int kok, int ll, int rr) {
 43         l[kok] = ll; r[kok] = rr;
 44         if (ll == rr) {
 45             maxx[kok] = h[ll];
 46             lmax[kok] = h[ll] - dist[ll];
 47             rmax[kok] = h[rr] + dist[rr];
 48             return ;
 49         }
 50         int m = mid[kok] = (ll + rr) >> 1;
 51         build(LSON(kok), ll, m); build(RSON(kok), m+1, rr);
 52         maxx[kok] = max(maxx[LSON(kok)], maxx[RSON(kok)]);
 53         maxx[kok] = max(maxx[kok], lmax[LSON(kok)] + rmax[RSON(kok)]);
 54         
 55 
 56         lmax[kok] = max(lmax[LSON(kok)], lmax[RSON(kok)]);
 57         rmax[kok] = max(rmax[LSON(kok)], rmax[RSON(kok)]);
 58 
 59     }
 60     void setting(int a = 0, int b = 0, int c = 0) {
 61         gx = a; gy = b; gz = c;
 62     }
 63     LL queryL(int kok) {
 64         if (gx <= l[kok] && r[kok] <= gy) {
 65             return lmax[kok];
 66         }
 67         if (gy <= mid[kok]) return queryL(LSON(kok));
 68         else if (gx > mid[kok]) return queryL(RSON(kok));
 69         else return max(queryL(LSON(kok)), queryL(RSON(kok)));
 70     }
 71     LL queryR(int kok) {
 72         if (gx <= l[kok] && r[kok] <= gy) {
 73             return rmax[kok];
 74         }
 75         if (gy <= mid[kok]) return queryR(LSON(kok));
 76         else if (gx > mid[kok]) return queryR(RSON(kok));
 77         else return max(queryR(LSON(kok)), queryR(RSON(kok)));
 78     }
 79 
 80 
 81     LL queryMax(int kok) {
 82         if (gx <= l[kok] && r[kok] <= gy) {
 83             return maxx[kok];
 84         }
 85         
 86         if (gy <= mid[kok]) return queryMax(LSON(kok));
 87         else if (gx > mid[kok]) return queryMax(RSON(kok));
 88         else return max(max(queryMax(LSON(kok)), queryMax(RSON(kok))), queryL(LSON(kok)) + queryR(RSON(kok)));
 89     }
 90 
 91 } Tree;
 92 
 93 #define INDEX(x) ((x)?(x):n)
 94 
 95 
 96 int main() {
 97 //    freopen("test.txt", "r", stdin);
 98 
 99 
100     scanf("%d%d", &n, &m);
101     for (int i = 1; i <= n; ++i) {
102         scanf("%d", &d[i]);
103         dist[i+1] = dist[i] + d[i];
104     }
105     for (int i = n; i < 2*n; ++i) {
106         dist[i+1] = dist[i] + d[(i%n)?(i%n):n];    
107     }
108     for (int i = 1; i <= n; ++i) {
109         scanf("%d", &h[i]); h[i] *= 2;
110     }    
111     for (int i = n+1; i <= 2*n; ++i) h[i] = h[i - n];
112 
113     Tree.build(1, 1, 2*n);
114     int x, y;
115     while (m--) {
116         int tx, ty;
117         scanf("%d%d", &x, &y);
118         if (x > y) y += n;
119         tx = y+1; ty = x + n - 1;
120         x = tx; y = ty;
121         x = INDEX(x%n); y = INDEX(y%n);
122         if (x > y) y += n;
123         Tree.setting(x, y);
124         cout << Tree.queryMax(1) << '\n';
125     }
126 
127     return 0;
128 }
CF 515E

 

posted @ 2016-08-11 10:14  F.D.His.D  阅读(261)  评论(0编辑  收藏  举报