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 76 77 78 79 80 81 82 83
| #include <cstdio> #include <cctype> #include <cstring> #include <algorithm> #include <vector> #include <queue> using namespace std; typedef long long int64; 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 = 12e4+5; int64 val[N<<2]; int c[N<<2], v[N<<2], ti[N<<2], a[N<<2]; void pusha(int x, int d) { v[x] += d, a[x] += d; } void pushti(int x, int d) { val[x] += d*c[x], ti[x] += d; } void pushdown(int x) { if(a[x]) pusha(x<<1, a[x]), pusha(x<<1|1, a[x]), a[x] = 0; if(ti[x]) { if(v[x] == v[x<<1]) pushti(x<<1, ti[x]); if(v[x] == v[x<<1|1]) pushti(x<<1|1, ti[x]); ti[x] = 0; } } void pushup(int x) { v[x] = max(v[x<<1], v[x<<1|1]); c[x] = 0; if(v[x] == v[x<<1]) c[x] += c[x<<1]; if(v[x] == v[x<<1|1]) c[x] += c[x<<1|1]; val[x] = val[x<<1]+val[x<<1|1]; } void build(int x, int l, int r) { if(l == r) return void(c[x] = 1); int mid = (l+r)>>1; build(x<<1, l, mid); build(x<<1|1, mid+1, r); } 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); } int64 query(int x, int l, int r, int ql, int qr) { if(ql <= l&&r <= qr) return val[x]; int mid = (l+r)>>1; int64 ret = 0; pushdown(x); if(ql <= mid) ret += query(x<<1, l, mid, ql, qr); if(qr > mid) ret += query(x<<1|1, mid+1, r, ql, qr); return ret; } int n, m, f[N], g[N]; vector<pair<int, int> > s[N]; int64 ans[N]; 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) { pusha(1, -1); change(1, 1, n, i, i, 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); pushti(1, 1); for(int k = 0; k < s[i].size(); ++k) ans[s[i][k].second] = query(1, 1, n, s[i][k].first, i); } for(int i = 1; i <= m; ++i) printf("%lld\n", ans[i]); return 0; }
|