二维偏序
二维偏序
二维偏序一般指这样一种问题:
比如:
有\(n\) 个点(或别的),都有两个属性,\(\{(a_1,b_1),(a_2,b_2)...\}\)并且对于其中两个点\(i 和 j\) 满足
\[\begin{cases}
i \leq j \leq n \\
a_i \leq a_j \\
b_i \leq b_j
\end{cases}
\]
一般解法是 排序一维 后 使用树状数组存储下一维的信息 ,有时候需要离散化
一些例题+code
const int maxn = 5e5 + 10;
int n,m;
int a[maxn],b[maxn],c[maxn];
int lowbit(int x) { return (x & (-x)); }
void add(int x) {
for(int i = x; i <= n; i += lowbit(i)) {
c[i]++;
}
}
int query(int x) {
int sum = 0;
for(int i = x ; i ; i -= lowbit(i)) {
sum += c[i];
}
return sum;
}
int main() {
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> b[i];
a[i] = b[i];
}
sort(a+1,a+1+n );
int m = unique(a+1,a+1+n) - a - 1;
for(int i = 1; i <= n; i++) {
b[i] = lower_bound(a+1,a+m+1,b[i] ) - a;
}
ll ans = 0;
for(int i = 1; i <= n; i++) {
add(b[i]);
ans += (i - query(b[i]));
}
cout << ans << "\n";
return 0;
}
int n,m;
int b[maxn],p[maxn];
int c1[maxn],c2[maxn];
struct node{
int x,v;
}a[maxn];
int lowbit(int x) { return x & -x; }
void add1(int x,int k) {
for(int i = x; i <= n; i += lowbit(i)) {
c1[i]++;
}
}
int que1(int x) {
int ans = 0 ;
for(int i = x; i; i -= lowbit(i)) {
ans += c1[i];
}
return ans;
}
void add2(int x,int k) {
for(int i = x; i <= n; i += lowbit(i)) {
c2[i] += k;
}
}
int que2(int x) {
int ans = 0 ;
for(int i = x; i; i -= lowbit(i)) {
ans += c2[i];
}
return ans;
}
pii v[maxn];
signed main() {
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i].x;
}
for(int i = 1; i <= n; i++) {
cin >> a[i].v;
b[i] = a[i].v;
}
sort(b+1,b+1+n);
m = unique(b+1,b+1+n) - b - 1;
for(int i = 1; i <= n; i++) {
a[i].v = lower_bound(b+1,b+1+n,a[i].v) - b;
}
sort(a+1,a+1+n,[](node x,node y){
return x.x < y.x;
});
ll ans = 0;
for(int i = 1; i <= n; i++) {
int cnt = que1(a[i].v);
int sum = que2(a[i].v);
ans += (cnt * a[i].x - sum);
add1(a[i].v,1);
add2(a[i].v,a[i].x);
}
cout << ans << "\n";
return 0;
}
这一题和上面哪一题非常像
int n,m;
int c1[maxn],c2[maxn];
int lowbit(int x) { return (x & -x); }
void add1(int x,int k) {
for(int i = x; i <= m; i += lowbit(i)) {
c1[i]++;
}
}
int que1(int x) {
int ans = 0;
for(int i = x; i; i -= lowbit(i)) {
ans += c1[i];
}
return ans;
}
void add2(int x,int k) {
for(int i = x; i <= m; i+= lowbit(i)) {
c2[i] += k;
}
}
int que2(int x) {
int ans = 0;
for(int i = x; i; i -= lowbit(i)) {
ans += c2[i];
}
return ans;
}
struct node{
int v,x;
}a[maxn];
signed main() {
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i].v >> a[i].x;
m = max(a[i].x,m);
}
sort(a+1,a+1+n,[](node a,node b){
return a.v < b.v;
});
ll ans = 0;
int p = 0;
for(int i = 1; i <= n; i++) {
int cnt = que1(a[i].x);
int sum = que2(a[i].x);
ans += (cnt * a[i].x - sum) * a[i].v;
ans += (p - sum - (i - cnt - 1)*a[i].x) * a[i].v;
add1(a[i].x, 1);
add2(a[i].x,a[i].x);
p += a[i].x;
}
cout << ans << "\n";
return 0;
}