HDU6318-2018ACM暑假多校联合训练2-1010-Swaps and Inversions-树状数组

本题题意是,给你一个长度为n的序列,使用最少的操作把序列转换为从小到大的顺序,并输出操作数*min(x,y)

实质上是算出该序列中有多少逆序对,有归并排序和树状数组两种算法,由于数据之间的差值有点大,所以使用树状数组时需要先离散化

离散化有两种方式,一种是先按value排,再按id排,另一种是按value排后,把重复的统一化

这里采用第一种方式

Swaps and Inversions

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1882    Accepted Submission(s): 686


Problem Description
Long long ago, there was an integer sequence a.
Tonyfang think this sequence is messy, so he will count the number of inversions in this sequence. Because he is angry, you will have to pay x yuan for every inversion in the sequence.
You don't want to pay too much, so you can try to play some tricks before he sees this sequence. You can pay y yuan to swap any two adjacent elements.
What is the minimum amount of money you need to spend?
The definition of inversion in this problem is pair  (i,j) which 1i<jn and ai>aj.
 
Input
There are multiple test cases, please read till the end of input file.
For each test, in the first line, three integers, n,x,y, n represents the length of the sequence.
In the second line, n integers separated by spaces, representing the orginal sequence a.
1n,x,y100000, numbers in the sequence are in [109,109]. There're 10 test cases.
 
Output
For every test case, a single integer representing minimum money to pay.
 
Sample Input
3 233 666
1 2 3
3 1 666
3 2 1
 
Sample Output
0
3
 1 #include <iostream>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 
 8 struct node
 9 {
10     int v, id;
11     bool operator < (const node &a) const
12     {
13         if (v == a.v)
14             return id < a.id;
15         return v < a.v;
16     }
17 }t[400010];
18 
19 int ch[400010];
20 int ch1[400010];
21 int n;
22 
23 void update(int x)
24 {
25     int temp = x;
26     while (temp <= n)
27     {
28         ch[temp]++;
29         temp += temp & (-x);
30     }
31 }
32 
33 int getsum(int x)
34 {
35     int sum = 0;
36     while (x)
37     {
38         sum += ch[x];
39         x -= x & (-x);
40     }
41     return sum;
42 }
43 
44 int main()
45 {
46     ios::sync_with_stdio(false);
47     int a, b;
48     while (cin>> n >> a >> b)
49     {
50         memset(ch, 0, sizeof(ch));
51         for (int i = 1; i <= n; i++)
52         {
53             cin >> t[i].v;
54             t[i].id = i;
55         }
56 
57         sort(t+1,t+n+1);
58 
59         long long ans = 0;
60         for (int i = 1; i <= n; i++)
61         {
62             update(t[i].id);
63             ans += i - getsum(t[i].id);
64         }
65         ans = min(ans*a, ans*b);
66         cout << ans << endl;
67     }
68     return 0;
69 }

猜你喜欢

转载自www.cnblogs.com/qq965921539/p/9389096.html
今日推荐