There is an infinite sequence consisting of all positive integers in the increasing order: p = {1, 2, 3, ...}. We performed n swap operations with this sequence. A swap(a, b) is an operation of swapping the elements of the sequence on positions a and b. Your task is to find the number of inversions in the resulting sequence, i.e. the number of such index pairs (i, j), that i < j and pi > pj.
The first line contains a single integer n (1 ≤ n ≤ 105) — the number of swap operations applied to the sequence.
Each of the next n lines contains two integers ai and bi (1 ≤ ai, bi ≤ 109, ai ≠ bi) — the arguments of the swap operation.
Print a single integer — the number of inversions in the resulting sequence.
2 4 2 1 4
4
3 1 6 3 4 2 5
15
In the first sample the sequence is being modified as follows: . It has 4 inversions formed by index pairs (1, 4), (2, 3), (2, 4) and (3, 4).
题意:对于一个1~n的序列,共有M次操作,每次操作交换i,j位置上的数,问逆序对数是多少
思路:因为n非常大,所以首先要离散化一下,还要注意的一点是,没有出现的位置(比如说样例1,1,2,4位置出现了,3没有出现)也会产生逆序对数,所以与处理一下排完序之后,两个位置之间有多少个数没有出现,再算答案的时候加上就可以了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100010;
typedef long long LL;
int num,N;
int sum[maxn*2];
int X[maxn*2];
int val[maxn*2];
int tree[maxn*2];
struct node
{
int x,y;
}a[maxn*2];
int getsum(int x)
{
int sum=0;
while(x)
{
sum+=tree[x];
x-=(x&(-x));
}
return sum;
}
void update(int x,int val)
{
while(x<=num)
{
tree[x]+=val;
x+=(x&(-x));
}
}
int main()
{
while(scanf("%d",&N)!=EOF)
{
num=0;
for(int i=1;i<=N;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
X[++num]=a[i].x;
X[++num]=a[i].y;
}
memset(tree,0,sizeof(tree));
memset(sum,0,sizeof(sum));
sort(X+1,X+num+1);
num=unique(X+1,X+1+num)-X-1;
for(int i=1;i<=num;i++)val[i]=X[i];
for(int i=1;i<=num;i++)sum[i]+=sum[i-1]+X[i]-X[i-1]-1;
for(int i=1;i<=N;i++)
{
int l=lower_bound(X+1,X+num+1,a[i].x)-X;
int r=lower_bound(X+1,X+1+num,a[i].y)-X;
swap(val[l],val[r]);
}
LL ans=0;
for(int i=1;i<=num;i++)
{
int pos=lower_bound(X+1,X+num+1,val[i])-X;
ans+=(LL)getsum(num)-getsum(pos-1);
ans+=(LL)abs(sum[pos]-sum[i]);
update(pos,1);
}
cout<<ans<<endl;
}
return 0;
}