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
| #include <bits/stdc++.h> using namespace std; const int N = 1e5 + 5, inf = 1e9; int n, a[N], sz[N]; int64_t ans; struct seg { int l, r, cnt; }t[N<<5]; int rt[N<<5], tot; void up(int p) { t[p].cnt = t[t[p].l].cnt + t[t[p].r].cnt; } void upd(int &p, int l, int r, int x) { if(!p) p = ++tot; t[p].cnt++; if(l==r) return; int mid = (l+r)>>1; if(x<=mid) upd(t[p].l, l, mid, x); else upd(t[p].r, mid+1, r, x); } int ask(int p, int l, int r, int v) { if(!p) return 0; if(r<=v) return t[p].cnt; int mid = (l+r)>>1; int ans = ask(t[p].l, l, mid, v); if(v>mid) ans += ask(t[p].r, mid+1, r, v); return ans; } int merge(int x, int y, int l, int r) { if(!x||!y) return x|y; if(l==r) { t[x].cnt += t[y].cnt; return x; } int mid = (l+r)>>1; t[x].l = merge(t[x].l, t[y].l, l, mid); t[x].r = merge(t[x].r, t[y].r, mid+1, r); up(x); return x; } int st[N], ch[N][2], top; void build() { top = 0; for(int i=1, j; i<=n; i++) { j = top; while(j&&a[st[j]]<a[i]) j--; if(j) ch[st[j]][1] = i; if(j<top) ch[i][0] = st[j+1]; top = j; st[++top] = i; } } void dfs(int p, int l, int r) { if(!p || l>r) return; dfs(ch[p][0], l, p-1); dfs(ch[p][1], p+1, r); sz[p] = sz[ch[p][0]] + sz[ch[p][1]] + 1; if(sz[ch[p][0]]<sz[ch[p][1]]) for(int i=l; i<=p-1; i++) ans += ask(rt[ch[p][1]], 1, inf, a[p]/a[i]); else for(int i=p+1; i<=r; i++) ans += ask(rt[ch[p][0]], 1, inf, a[p]/a[i]); rt[p] = merge(rt[ch[p][0]], rt[ch[p][1]], 1, inf); upd(rt[p], 1, inf, a[p]); ans += ask(rt[p], 1, inf, 1); } int main() { scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%d", a+i); build(); dfs(st[1], 1, n); printf("%lld\n", ans); return 0; }
|