求逆序数的两个方法
1.归并排序
#include <iostream> using namespace std; const int maxn = 1000; int a[maxn],b[maxn]; int ans; void merge_sort(int x,int y){ if(y-x>1) { int m = x+(y-x)/2; int p = x, q = m,i = x; merge_sort(x,m); merge_sort(m,y); while(p<m||q<y){ if(q>=y||(p<m&&a[p]<=a[q])) b[i++] = a[p++]; else {b[i++]=a[q++];ans+=m-p;} } for(int i = x;i<y;i++) a[i] = b[i]; } } int main() { int n; while(cin>>n){ for(int i=0;i<n;i++) cin>>a[i]; ans=0; merge_sort(0,n); cout<<ans<<endl; for(int i=0;i<n;i++) cout<<a[i]<<" ";cout<<endl; } return 0; }
2.离散+树状数组
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).
离散:
逆序数组:9 1 0 5 4 --> 5 2 1 4 3
这题有点特别:就是先把那些交换的点+那些中间的点(等价的几个,所以a[i].yy可能大于1)
注意:maxn要为4*1e5,因为不单只2倍的10的5次方操作!
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <algorithm> #include <queue> #include <cmath> #include <stack> #include <iomanip> #include <map> #define sc scanf #define pf printf #define REP(i,a,b) for(int i=(a);i<(b);i++) #define CLR(x,m) memset(x,m,sizeof x); #define LOCAL freopen("test.txt","r",stdin) #define UCCU ios::sync_with_stdio(0); #define XSD(i) cout << fixed << setprecision(i); #define pii pair<int,int> #define xx first #define yy second using namespace std; typedef long long LL; typedef double DB; const double eps = 1e-6; const int maxn = 400100; map<int,int> mp,mp2; map<int, int> :: iterator it; pii a[maxn]; int b[maxn]; LL fen[maxn]; void add(int n, int k) { for(; n < maxn; n += n & (-n)) fen[n] += k; } int get(int n) { int res = 0; for(; n > 0; n -= n & (-n)) res += fen[n]; return res; } void run() { int n; cin>>n; REP(i,0,n){ int u,v;cin>>u>>v; if(!mp[u]) mp[u]=u; if(!mp[v]) mp[v]=v; int temp = mp[u]; mp[u] = mp[v]; mp[v] = temp; } int pre=1,num=0; for(it = mp.begin();it!=mp.end();++it){ int x = (*it).xx;int y = (*it).yy; if(x!=1&&x-pre-1){ a[++num]=pii(x-1,x-pre-1); b[num]=x-1; } a[++num]=pii(y,1); b[num]=y; pre=x; } sort (b + 1, b + 1 + num); for (int i = 1; i <= num; i++) { mp2[b[i]] = i; } for (int i = 1; i <= num; i++) { a[i].xx = mp2[a[i].xx]; } LL ans =0,tot=0; REP(i,1,num+1){ ans+=1LL * (tot-get(a[i].xx))*a[i].yy; add(a[i].xx,a[i].yy); tot+=a[i].yy; } cout<<ans<<endl; } int main() { //LOCAL; UCCU;//cin.tie(); run(); return 0; }