社区讨论
萌新求问空间复杂度
P4755Beautiful Pair参与者 3已保存回复 6
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 6 条
- 当前快照
- 1 份
- 快照标识符
- @lo12j1sz
- 此快照首次捕获于
- 2023/10/22 14:08 2 年前
- 此快照最后确认于
- 2023/11/02 13:37 2 年前
rt,不想写离散化所以写的动态开点线段树然而还是离散化更好写,我自己算了一下是 的,但是开 倍过了,所以是数据水还是跑不满还是我算错了。
附代码
CPP#include <bits/stdc++.h>
#define ll long long
using namespace std; const int N = 1e5 + 5, V = 1e9; int n, a[N], pre[N];
template<class T> void read(T &x) {
x = 0; T f = 1; char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -1;
for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - 48; x *= f;
}
template<class T> void write(T x) {
if (x > 9) write(x / 10); putchar(x % 10 + 48);
}
template<class T> void print(T x, char ed = '\n') {
if (x < 0) putchar('-'), x = -x; write(x), putchar(ed);
}
struct SegmentTree {
int rt, sum[N * 16], ls[N * 16], rs[N * 16], cnt;
SegmentTree() {
memset(ls, 0, sizeof ls); memset(rs, 0, sizeof rs);
memset(sum, rt = cnt = 0, sizeof sum);
}
void upd(int &x, int l, int r, int k, int v) {
if (!x) x = ++cnt; if (l == r) return void(sum[x] += v);
int mid = (l + r) >> 1;
if (k <= mid) upd(ls[x], l, mid, k, v); else upd(rs[x], mid + 1, r, k, v);
sum[x] = sum[ls[x]] + sum[rs[x]];
}
int qry(int x, int l, int r, int ql, int qr) {
if (!x) return 0; if (ql <= l && r <= qr) return sum[x];
int mid = (l + r) >> 1, ret = 0;
if (ql <= mid) ret = qry(ls[x], l, mid, ql, qr);
if (qr > mid) ret = ret + qry(rs[x], mid + 1, r, ql, qr); return ret;
}
void clr(int x, int l, int r, int k) {
if (!x) return; sum[x] = 0; if (l == r) return; int mid = (l + r) >> 1;
if (k <= mid) clr(ls[x], l, mid, k); else clr(rs[x], mid + 1, r, k);
}
} T1, T2;
ll F(int l, int r) {
if (l == r) return a[l] == 1; int mid = (l + r) >> 1; ll ret = 0;
for (int i = mid + 1; i <= r; ++i) {
pre[i] = max(pre[i - 1], a[i]); T2.upd(T2.rt, 0, V, pre[i] / a[i], 1);
}
for (int i = mid, j = mid + 1, mx = 0; i >= l; --i) {
mx = max(mx, a[i]);
for (; j <= r && pre[j] <= mx; ++j)
T1.upd(T1.rt, 0, V, a[j], 1), T2.upd(T2.rt, 0, V, pre[j] / a[j], -1);
ret += T1.qry(T1.rt, 0, V, 0, mx / a[i]) + T2.qry(T2.rt, 0, V, a[i], V);
}
for (int i = mid + 1; i <= r; ++i)
T1.clr(T1.rt, 0, V, a[i]), T2.clr(T2.rt, 0, V, pre[i] / a[i]);
for (int i = mid + 1; i <= r; ++i) pre[i] = 0;
return ret + F(l, mid) + F(mid + 1, r);
}
signed main() {
read(n); for (int i = 1; i <= n; ++i) read(a[i]); return print(F(1, n)), 0;
}
回复
共 6 条回复,欢迎继续交流。
正在加载回复...