【题解】洛谷P2448: 无尽的生命
P2448 无尽的生命
这题难的不是逆序对模板,主要是如何处理不会操作的数,我们交换操作的与不操作的数可以分割出区间,每个区间我们都当作一个独立的个体。
这个图就可以划分出以下区间(起始编号,区间个数)(1,1),(2,2),(4,1),(5,1),(6,1),(7,1)
此时我们对查询交换区间进行离散化,对新的区间编号,再进行交换和逆序对操作,注意此时求逆序对个数需要乘上区间个数。
#include<bits/stdc++.h>
#define int long long
#define re register
const int N=1e6+10;
const int mod=998244353;
using namespace std;
int n;
int b[N],o=0;
int idx[N],idy[N];
int t[N],row[N];
int a[N],id[N];
int tree[N];
int len;
int lb(int x){
return x&-x;
}
void add(int x,int k){
while(x<=len){
tree[x]+=k;
x+=lb(x);
}
}
int query(int x){
int sum=0;
while(x){
sum+=tree[x];
x-=lb(x);
}
return sum;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n;
for(int i=1;i<=n;i++){
int x,y;
cin>>x>>y;
idx[i]=x;
idy[i]=y;
b[++o]=x;
b[++o]=y;
}
sort(b+1,b+o+1);
int tot=unique(b+1,b+o+1)-b-1;
len=0;
row[++len]=b[1];
t[len]=1;
for(int i=2;i<=tot;i++){
if(b[i]-b[i-1]>1){
row[++len]=b[i-1]+1;
t[len]=b[i]-b[i-1]-1;
}
row[++len]=b[i];
t[len]=1;
}
for(int i=1;i<=len;i++){
id[i]=i;
}
for(int i=1;i<=n;i++){
int x=lower_bound(row+1,row+1+len,idx[i])-row;
int y=lower_bound(row+1,row+1+len,idy[i])-row;
swap(t[x],t[y]);
swap(id[x],id[y]);
}
int ans=0;
for(int i=len;i>=1;i--){
ans+=query(id[i]-1)*t[i];
add(id[i],t[i]);
}
cout<<ans;
return 0;
}