排序工作量
题目来源
COGS,两题
排序工作量:http://cojs.tk/cogs/problem/problem.php?pid=382
排序工作量-加强版:http://cojs.tk/cogs/problem/problem.php?pid=477
题目描述
直接告诉你求逆序对数。
第一题是实数,第二题是正整数(但测试数据里出现了0,不要在意这些细节虽然我因为这个TTTTATTTTT了)
分析
用树状数组求逆序对数。
从左往右,对于第i个,每次先询问已经插入的(也就是左边的)比i大的有多少个,然后插入i。
最后所有询问的和sum就是答案。
第一题因为是实数,先排序了。
1 /************************************************** 2 Source: COGS 382 3 Author: Xue Zhonghao 4 Date: 2014-4-20 18:19:46 5 State: Accepted 6 **************************************************/ 7 #include<cstdio> 8 #include<cstdlib> 9 #include<fstream> 10 using namespace std; 11 ifstream fin("sortt.in"); 12 ofstream fout("sortt.out"); 13 14 #define lowbit(x) ((x)&(-(x))) 15 #define MAXN 50010 16 17 struct saver { 18 double x; 19 int w; 20 }; 21 22 saver Ori[MAXN]; 23 int A[MAXN], C[MAXN]; 24 int N; 25 26 void add(int x, int d) { 27 while(x <= N) { 28 C[x] += d; x += lowbit(x); 29 } 30 } 31 32 int sum(int x) { 33 int ans = 0; 34 while(x > 0) { 35 ans += C[x]; x -= lowbit(x); 36 } 37 return ans; 38 } 39 40 int cmp(const void *a, const void *b) { 41 saver x = *(saver *)a; 42 saver y = *(saver *)b; 43 return x.x > y.x; 44 } 45 46 int main(void) 47 { 48 fin>>N; 49 for(int i = 0; i < N; ++i) { 50 fin>>Ori[i].x; 51 Ori[i].w = i+1; 52 } 53 qsort(Ori, N, sizeof(saver), cmp); 54 for(int i = 0; i < N; ++i) { 55 A[Ori[i].w] = i+1; 56 } 57 int ans = 0; 58 for(int i = 1; i <= N; ++i) { 59 ans += sum(N) - sum(A[i]); 60 add(A[i], 1); 61 } 62 fout<<ans<<endl; 63 return 0; 64 }
1 /************************************************** 2 Source: COGS 477 3 Author: Xue Zhonghao 4 Date: 2014-4-20 19:14:24 5 State: Accepted 6 **************************************************/ 7 #include<cstdio> 8 #include<cstdlib> 9 #include<fstream> 10 using namespace std; 11 ifstream fin("px.in"); 12 ofstream fout("px.out"); 13 14 #define lowbit(x) ((x)&(-(x))) 15 #define MAXN 50010 16 #define SID 2000010 17 #define LL long long 18 19 int A[MAXN], C[SID]; 20 int N; 21 22 void add(int x, int d) { 23 while(x <= SID) { 24 C[x] += d; x += lowbit(x); 25 } 26 } 27 28 int sum(int x) { 29 int ans = 0; 30 while(x > 0) { 31 ans += C[x]; x -= lowbit(x); 32 } 33 return ans; 34 } 35 36 int main(void) 37 { 38 fin>>N; 39 for(int i = 1; i <= N; ++i) { fin>>A[i]; A[i]++; } 40 LL ans = 0; 41 for(int i = 1; i <= N; ++i) { 42 ans += sum(N) - sum(A[i]); 43 add(A[i], 1); 44 } 45 fout<<ans<<endl; 46 return 0; 47 }