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 84 85 86 87 88 89 90
|
#pragma GCC optimize("Ofast,no-stack-protector") #pragma GCC target("avx2,fma") #include <map> #include <cstdio> #include <iostream> #include <algorithm> #define LL long long #define ULL unsigned long long using namespace std; const int MAXN = 1e5 + 5; const int INF = 0x3f3f3f3f;
template <typename T> inline void read(T& x) { x = 0; int f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -f; c = getchar(); } while (c >= '0' && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); } x *= f; } template <typename T, typename... Args> inline void read (T &x, Args&... Arg) { read (x), read (Arg...); } template <typename T> inline T Abs(T x) { return x < 0 ? -x : x; } template <typename T> inline T Max(T x, T y) { return x > y ? x : y; } template <typename T> inline T Min(T x, T y) { return x < y ? x : y; }
int n, len, cnt, a[MAXN], b[MAXN]; LL res;
int ind(int x) { return upper_bound(b, b + len + 1, x) - b; } struct CartesianTree { int sta[MAXN], tp, root; struct Node { int l, r; } s[MAXN << 2]; void build(int n, int val[]) { int maxl = -INF; val[sta[tp]] = INF; for (int i = 1; i <= n; i++) { bool flag = false; if (val[i] > maxl) maxl = val[i], root = i; while (val[i] > val[sta[tp]]) tp--, flag = true; s[sta[tp]].r = i; if (flag) s[i].l = sta[tp + 1]; sta[++tp] = i; } } } ct; struct FenwickTree { int s[MAXN]; int lowbit(int x) { return x & -x; } void update(int pos, int delta) { for (int i = pos; i <= n; i += lowbit(i)) s[i] += delta; } int query(int pos) { int res = 0; for (int i = pos; i; i -= lowbit(i)) res += s[i]; return res; } } ft;
void operate(int l, int r, int u, int opt) { for (int i = l; i <= r; i++) { int pos = ind(b[a[u]] / b[a[i]]); if (pos) res += opt * ft.query(pos - 1); } } void dfs(int u, int l, int r) { if (u == 0) return; if (u - l > r - u) operate(u, r, u, -1), dfs(ct.s[u].l, l, u - 1), ft.update(a[u], 1), operate(u, r, u, +1), dfs(ct.s[u].r, u + 1, r); else operate(l, u, u, -1), dfs(ct.s[u].r, u + 1, r), ft.update(a[u], 1), operate(l, u, u, +1), dfs(ct.s[u].l, l, u - 1); }
int main() {
read(n); for (int i = 1; i <= n; i++) read(a[i]), b[i] = a[i];
sort(b + 1, b + 1 + n), len = unique(b + 1, b + 1 + n) - b - 1; for (int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + 1 + len, a[i]) - b;
ct.build(n, a); dfs(ct.root, 1, n); printf("%lld\n", res);
return 0; }
|