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 }