可持久化线段树 CF484E-Sign on Fence

来源:互联网 发布:淘宝盗图怎么投诉 编辑:程序博客网 时间:2024/05/30 04:31

题目链接

题目大意:1-n每个位置上有一个固定高度的建筑物,有若干次询问,每次询问 [l, r] 区间内,连续横跨长度为w,高度最矮的建筑物最高为多少。

解题思路:可持久化线段树,按高度为建树,每次询问为针对一段区间,最长的连续和为多少。

#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>#include <iomanip>#include <iostream>#include <cassert>#include <map>#include <set>#include <queue>#include <stack>#include <vector>#include <unordered_set>#include <unordered_map>#define  RD(x)      scanf("%d", &x)#define  REP(i, n)  for (int i=0; i<int(n); i++)#define  FOR(i, n)  for (int i=1; i<=int(n); i++)#define  pii        pair<int, int>#define  mp         make_pair#define  pb         push_backinline   int read(){int ret; scanf("%d", &ret); return ret;}//int dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};//int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};int dx[4] = {1, 0, -1, 0};int dy[4] = {0, 1, 0, -1};using namespace std;#define  N   123456#define  M   22222#define  eps 1e-8#define  pi  acos(-1.0)#define  inf 0X5FFFFFFFFFFFFFFFll#define  mod 1000000007ll#define  LL  long long#define  ULL unsigned long longstruct Seg {Seg *l, *r;int ll, rr, len, d;void pushUp() {len = max((l?l->rr:0) + (r?r->ll:0),max(l?l->len:0, r?r->len:0));ll = l?l->ll:0;if (l && r && l->len == l->d)ll = l->d + r->ll;rr = r?r->rr:0;if (l && r && r->len == r->d)rr = r->d + l->rr;}}pool[N*20], *cur = pool;Seg *root[N];Seg *newNode(int l, int r) {cur->l = cur->r = NULL;cur->ll = cur->rr = cur->len = 0;cur->d = r - l + 1;return cur++;}Seg *update(int x, int l, int r, Seg *now) {Seg *ret = newNode(l, r);if (now != NULL)*ret = *now;if (l == r) {ret->ll = ret->rr = ret->len = 1;return ret;}int mid = (l + r) >> 1;if (x <= mid)ret->l = update(x, l, mid, now?now->l:NULL);if (x > mid)ret->r = update(x, mid+1, r, now?now->r:NULL);ret->pushUp();return ret;}Seg *p0[N];int tot;void _query(int l, int r, int L, int R, Seg *now) {if (l <= L && R <= r) {p0[tot++] = now;return;}int mid = (L + R) >> 1;if (l <= mid)_query(l, r, L, mid, now?now->l:NULL);if (r > mid)_query(l, r, mid+1, R, now?now->r:NULL);}int query(int l, int r, int L, int R, Seg *now) {tot = 0;_query(l, r, L, R, now);int pre = 0;int ret = 0;REP(i, tot) {pre += p0[i]?p0[i]->ll:-pre;ret = max(ret, max(pre, p0[i]?p0[i]->len:0));pre = p0[i]?(p0[i]->len == p0[i]->d? pre:p0[i]->rr):0;}return ret;}pii h[N];int height[N];int Main() {//freopen("cf.txt", "r", stdin);ios_base::sync_with_stdio(0);int n, m;cin >> n;FOR(i, n) {cin >> h[i].first;h[i].second = i;}sort(h + 1, h + n + 1, [](const pii &a, const pii &b) {return a.first > b.first;});FOR(i, n)root[i] = update(h[i].second, 1, n, root[i-1]);cin >> m;while (m--) {int L, R, W;cin >> L >> R >> W;int l = 1, r = n;while (l < r) {int mid = (l + r) >> 1;if (query(L, R, 1, n, root[mid]) >= W)r = mid;elsel = mid + 1;}cout << h[l].first << endl;}return 0;}int main() {return Main();}


0 0