社区讨论
求助写法
P3810【模板】三维偏序 / 陌上花开参与者 5已保存回复 8
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @lvggv7rh
- 此快照首次捕获于
- 2024/04/26 17:24 2 年前
- 此快照最后确认于
- 2024/04/26 18:09 2 年前
求问以下两种写法为何第一种能过第二种不行,两种都可过样例。
CPP#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = 2e5 + 10;
int n, k, ans[M];
namespace BIT {
int B[M];
void add(int x, int y) {
for(; x <= k; x += (x & -x)) B[x] += y;
}
int ask(int x) {
int sum = 0;
for(; x > 0; x -= (x & -x)) sum += B[x];
return sum;
}
}
using namespace BIT;
struct node {
int a, b, c, cnt, res;
bool operator != (node rhs) {
return (a != rhs.a || b != rhs.b || c != rhs.c);
}
} c[N], lsh[N];
void cdq(int l, int r) {
if(l == r) return;
int mid = ((l + r) >> 1);
cdq(l, mid); cdq(mid + 1, r);
sort(lsh + l, lsh + mid + 1, [](node x, node y) {
if(x.b != y.b) return x.b < y.b;
else return x.c < y.c;
});
sort(lsh + mid + 1, lsh + r + 1, [](node x, node y) {
if(x.b != y.b) return x.b < y.b;
else return x.c < y.c;
});
int i = l, j = mid + 1;
for(; j <= r; j++) {
for(; i <= mid && lsh[i].b <= lsh[j].b; i++) add(lsh[i].c, lsh[i].cnt);
lsh[j].res += ask(lsh[j].c);
}
for(int t = l; t < i; t++) add(lsh[t].c, -lsh[t].cnt);
}
int main() {
cin >> n >> k;
for(int i = 1; i <= n; i++) {
cin >> c[i].a >> c[i].b >> c[i].c;
}
sort(c + 1, c + n + 1, [](node x, node y) {
if(x.a != y.a) return x.a < y.a;
else if(x.b != y.b) return x.b < y.b;
else return x.c < y.c;
});
int tot = 0, cnt = 0;
for(int i = 1; i <= n; i++) {
cnt++;
if(c[i] != c[i + 1]) {
lsh[++tot] = {c[i].a, c[i].b, c[i].c, cnt, 0};
cnt = 0;
}
}
cdq(1, tot);
for(int i = 1; i <= tot; i++) ans[lsh[i].res + lsh[i].cnt - 1] += lsh[i].cnt;
for(int i = 0; i < n; i++) cout << ans[i] << '\n';
return 0;
}
接下来是第二种
CPP#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = 2e5 + 10;
int n, k, ans[M];
namespace BIT {
int B[M];
void add(int x, int y) {
for(; x <= k; x += (x & -x)) B[x] += y;
}
int ask(int x) {
int sum = 0;
for(; x > 0; x -= (x & -x)) sum += B[x];
return sum;
}
}
using namespace BIT;
struct node {
int a, b, c, cnt, res;
bool operator == (node rhs) {
return (a == rhs.a && b == rhs.b && c == rhs.c);
}
bool operator < (node rhs) {
if(a != rhs.a) return a < rhs.a;
else if(b != rhs.b) return b < rhs.b;
else return c < rhs.c;
}
} c[N];
void cdq(int l, int r) {
if(l == r) return;
int mid = ((l + r) >> 1);
cdq(l, mid); cdq(mid + 1, r);
sort(c + l, c + mid + 1, [](node x, node y) {
if(x.b != y.b) return x.b < y.b;
else return x.c < y.c;
});
sort(c + mid + 1, c + r + 1, [](node x, node y) {
if(x.b != y.b) return x.b < y.b;
else return x.c < y.c;
});
int i = l, j = mid + 1;
for(; j <= r; j++) {
for(; i <= mid && c[i].b <= c[j].b; i++) add(c[i].c, c[i].cnt);
c[j].res += ask(c[j].c);
}
for(int t = l; t < i; t++) add(c[t].c, -c[t].cnt);
}
int main() {
cin >> n >> k;
for(int i = 1; i <= n; i++) {
cin >> c[i].a >> c[i].b >> c[i].c;
c[i].cnt = 1; c[i].res = 0;
}
sort(c + 1, c + n + 1);
int tot = unique(c + 1, c + n + 1) - c - 1;
sort(c + tot + 1, c + n + 1);
for(int l = 1, r = tot + 1; r <= n && l <= tot; r++) {
while(l <= tot && c[l] < c[r]) l++;
c[l].cnt++;
}
cdq(1, tot);
for(int i = 1; i <= tot; i++) ans[c[i].res + c[i].cnt - 1] += c[i].cnt;
for(int i = 0; i < n; i++) cout << ans[i] << '\n';
return 0;
}
回复
共 8 条回复,欢迎继续交流。
正在加载回复...