Codeforces Round #301 (Div. 2) E. Infinite Inversions —— 逆序对 离散化 + 树状数组
Posted dolfamingo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #301 (Div. 2) E. Infinite Inversions —— 逆序对 离散化 + 树状数组相关的知识,希望对你有一定的参考价值。
题目链接:http://codeforces.com/contest/540/problem/E
方法一:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <cstdlib> 6 #include <string> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #include <queue> 11 #include <sstream> 12 #include <algorithm> 13 using namespace std; 14 typedef long long LL; 15 const double eps = 1e-8; 16 const int INF = 2e9; 17 const LL LNF = 9e18; 18 const int MOD = 1e9+7; 19 const int MAXN = 2e5+10; 20 21 int c[MAXN]; 22 int lowbit(int x) 23 { 24 return x&(-x); 25 } 26 27 void add(int x, int d) 28 { 29 for(; x<MAXN; x += lowbit(x)) 30 c[x] += d; 31 } 32 33 int sum(int x) 34 { 35 int ret = 0; 36 for(; x>0; x -= lowbit(x)) 37 ret += c[x]; 38 return ret; 39 } 40 41 int query(int l, int r) 42 { 43 if(l>r) return 0; 44 return sum(r)-sum(l-1); 45 } 46 47 int x[MAXN], y[MAXN], a[MAXN], pre[MAXN], now[MAXN]; 48 map<int,int>M; 49 int main() 50 { 51 int n; 52 while(scanf("%d",&n)!=EOF) 53 { 54 M.clear(); 55 for(int i = 1; i<=n; i++) 56 { 57 scanf("%d%d",&x[i],&y[i]); 58 a[i] = x[i]; a[n+i] = y[i]; 59 } 60 sort(a+1,a+1+2*n); 61 int m = unique(a+1,a+1+2*n)-(a+1); 62 memcpy(pre+1, a+1, m*sizeof(a[1])); 63 memcpy(now+1, a+1, m*sizeof(a[1])); 64 for(int i = 1; i<=m; i++) 65 M[now[i]] = i; 66 67 for(int i = 1; i<=n; i++) 68 { 69 swap(now[M[x[i]]], now[M[y[i]]]); 70 swap(M[x[i]], M[y[i]]); 71 } 72 73 LL ans = 0; 74 memset(c, 0, sizeof(c)); 75 for(int i = 1; i<=m; i++) 76 { 77 int pre_pos = upper_bound(pre+1,pre+1+m, now[i])-(pre+1); 78 int now_pos = i; 79 ans += query(pre_pos+1,m); 80 add(pre_pos, 1); 81 82 if(pre[i]>now[i]) ans += (pre[i]-now[i])-(now_pos-pre_pos); 83 if(pre[i]<now[i]) ans += (now[i]-pre[i])-(pre_pos-now_pos); 84 } 85 printf("%lld\n",ans); 86 } 87 }
方法二:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <cstdlib> 6 #include <string> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #include <queue> 11 #include <sstream> 12 #include <algorithm> 13 using namespace std; 14 typedef long long LL; 15 const double eps = 1e-8; 16 const int INF = 2e9; 17 const LL LNF = 9e18; 18 const int MOD = 1e9+7; 19 const int MAXN = 4e5+10; 20 21 struct node 22 { 23 int val, cnt; 24 }b[MAXN]; 25 26 int c[MAXN]; 27 int lowbit(int x) 28 { 29 return x&(-x); 30 } 31 32 void add(int x, int d) 33 { 34 for(; x<MAXN; x += lowbit(x)) 35 c[x] += d; 36 } 37 38 int sum(int x) 39 { 40 int ret = 0; 41 for(; x>0; x -= lowbit(x)) 42 ret += c[x]; 43 return ret; 44 } 45 46 int query(int l, int r) 47 { 48 if(l>r) return 0; 49 return sum(r)-sum(l-1); 50 } 51 52 int x[MAXN], y[MAXN], a[MAXN]; 53 map<int,int>M, MM; 54 int main() 55 { 56 int n; 57 while(scanf("%d",&n)!=EOF) 58 { 59 M.clear(); 60 MM.clear(); 61 for(int i = 1; i<=n; i++) 62 { 63 scanf("%d%d",&x[i],&y[i]); 64 a[i] = x[i]; a[n+i] = y[i]; 65 } 66 sort(a+1,a+1+2*n); 67 int m = unique(a+1,a+1+2*n)-(a+1); 68 int cnt = 0, st = 1; 69 for(int i = 1; i<=m; i++) 70 { 71 if(st!=a[i]) 72 { 73 b[++cnt].val = st; 74 b[cnt].cnt = a[i]-st; 75 M[b[cnt].val] = MM[b[cnt].val] = cnt; 76 } 77 b[++cnt].val = a[i]; 78 b[cnt].cnt = 1; 79 M[b[cnt].val] = MM[b[cnt].val] = cnt; 80 st = a[i]+1; 81 } 82 m = cnt; 83 84 for(int i = 1; i<=n; i++) 85 { 86 swap(b[MM[x[i]]], b[MM[y[i]]]); 87 swap(MM[x[i]], MM[y[i]]); 88 } 89 90 memset(c, 0,sizeof(c)); 91 LL ans = 0; 92 for(int i = 1; i<=m; i++) 93 { 94 ans += 1LL*b[i].cnt*query(M[b[i].val]+1, m); 95 add(M[b[i].val], b[i].cnt); 96 } 97 printf("%lld\n",ans); 98 } 99 }
以上是关于Codeforces Round #301 (Div. 2) E. Infinite Inversions —— 逆序对 离散化 + 树状数组的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #301 (Div. 2) E. Infinite Inversions —— 逆序对 离散化 + 树状数组
「日常训练」Bad Luck Island(Codeforces Round 301 Div.2 D)
「日常训练」Paths and Trees(Codeforces Round 301 Div.2 E)
「日常训练」Ice Cave(Codeforces Round 301 Div.2 C)