1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| #include <cstdio> #include <algorithm> #include <cctype> #include <vector> #include <queue> using namespace std; inline int read(int f = 1, int x = 0, char ch = ' ') { while(!isdigit(ch = getchar())) if(ch == '-') f = -1; while(isdigit(ch)) x = x*10+ch-'0', ch = getchar(); return f*x; } const int N = 1e5+5; int n, m; int val[N<<2], add[N<<2], p[N<<2]; void pusha(int x, int d) { add[x] += d, val[x] += d; } void pushdown(int x) { if(add[x]) pusha(x<<1, add[x]), pusha(x<<1|1, add[x]), add[x] = 0; } void pushup(int x) { if(val[x<<1] > val[x<<1|1]) p[x] = p[x<<1], val[x] = val[x<<1]; else val[x] = val[x<<1|1], p[x] = p[x<<1|1]; } void build(int x, int l, int r) { if(l == r) return void(val[x] = p[x] = l); int mid = (l+r)>>1; build(x<<1, l, mid), build(x<<1|1, mid+1, r); pushup(x); } void change(int x, int l, int r, int ql, int qr, int d) { if(ql <= l&&r <= qr) return pusha(x, d); int mid = (l+r)>>1; pushdown(x); if(ql <= mid) change(x<<1, l, mid, ql, qr, d); if(qr > mid) change(x<<1|1, mid+1, r, ql, qr, d); pushup(x); } int ansl, ansr; void query(int x, int l, int r, int ql, int qr) { if(ql <= l&&r <= qr) return (void)(ansl = ansr<=val[x]?p[x]:ansl, ansr = max(ansr, val[x])); int mid = (l+r)>>1; pushdown(x); if(ql <= mid) query(x<<1, l, mid, ql, qr); if(qr > mid) query(x<<1|1, mid+1, r, ql, qr); } pair<int, int> ans[N]; bool valid(pair<int, int> p, int r) { ansr = -1; query(1, 1, n, 1, p.first); if(ansr == r) return ans[p.second] = make_pair(ansl, ansr), true; else return false; } int f[N], g[N]; vector<pair<int, int> > s[N]; priority_queue<pair<int, int> > q; int main() { n = read(); build(1, 1, n); for(int i = 1; i <= n; ++i) f[i] = read(), g[f[i]] = i; m = read(); for(int i = 1; i <= m; ++i) { int l = read(), r = read(); s[r].push_back(make_pair(l, i)); } for(int i = 1; i <= n; ++i) { if(f[i] != 1&&g[f[i]-1] < i) change(1, 1, n, 1, g[f[i]-1], 1); if(f[i] != n&&g[f[i]+1] < i) change(1, 1, n, 1, g[f[i]+1], 1); for(int k = 0; k < s[i].size(); ++k) q.push(s[i][k]); while(q.size()&&valid(q.top(), i)) q.pop(); } for(int i = 1; i <= m; ++i) printf("%d %d\n", ans[i].first, ans[i].second); return 0; }
|