这题目意思很简单,就是给你一个数组,然后让你重新排好序,排序有要求的,每次只能交换两个元素的位置,交换需要一个代价 就是两个元素之和,问你把数组重小到大排好最少需要多少代价
可能一开始想不到逆序数,我是专门做专题往那边想才想到的,举个例子吧
数组: 9 1 0 5 4
此时到 0 的时候,我们先手写一下最小代价,然后再按照自己的猜测去看看,就是当前扫到0,那么前面比它大的数有2个,所以先 部分代价为 2 * 0,然后再加上前面比它大的数 也就是9 和1 ,那么最小代价为10,发现跟手算的一样,那么 再多试几个 最后我们就发现了
对于当前数num,前面有x个比它大的数,那么走到当前一步的 最小代价为 x*num 再加上前面比它大的数之和
这样就很容易跟树状数组扯上关系了,当前一步的逆序数 其实就是 前面比它大的数的个数,然后同时又能用树状数组对于前面比它大的数求和,这样问题就完美解决了,一开始我看n是10^5次,可能还是没经验把,觉得有可能会超,所以就先离散化的做了一遍,可是总是WA,然后离散化去掉以后就过了,不知道为什么,可是用过掉的代码跑了很多案例,发现跟离散化版本的 答案是一样的,真心不知道哪里写错了
可能一开始想不到逆序数,我是专门做专题往那边想才想到的,举个例子吧
数组: 9 1 0 5 4
此时到 0 的时候,我们先手写一下最小代价,然后再按照自己的猜测去看看,就是当前扫到0,那么前面比它大的数有2个,所以先 部分代价为 2 * 0,然后再加上前面比它大的数 也就是9 和1 ,那么最小代价为10,发现跟手算的一样,那么 再多试几个 最后我们就发现了
对于当前数num,前面有x个比它大的数,那么走到当前一步的 最小代价为 x*num 再加上前面比它大的数之和
这样就很容易跟树状数组扯上关系了,当前一步的逆序数 其实就是 前面比它大的数的个数,然后同时又能用树状数组对于前面比它大的数求和,这样问题就完美解决了,一开始我看n是10^5次,可能还是没经验把,觉得有可能会超,所以就先离散化的做了一遍,可是总是WA,然后离散化去掉以后就过了,不知道为什么,可是用过掉的代码跑了很多案例,发现跟离散化版本的 答案是一样的,真心不知道哪里写错了
离散化的贴出来,希望路过大神 指点:
#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#include<cctype>
#define ll long long
#define LL __int64
#define eps 1e-8
//const ll INF=9999999999999;
#define inf 0xfffffff
using namespace std;
//vector<pair<int,int> > G;
//typedef pair<int,int> P;
//vector<pair<int,int>> ::iterator iter;
//
//map<ll,int>mp;
//map<ll,int>::iterator p;
const int N = 500000 + 10;
int a[N];
int aa[N];
int n;
typedef struct Node {
int v;//原数字
int id;//下标
};
Node p[N];
typedef struct C {
LL sum;
int id;
};
C c[N];
void clear() {
memset(c,0,sizeof(c));
memset(aa,0,sizeof(aa));
memset(p,0,sizeof(p));
}
bool cmp(Node x,Node y) {
return x.v < y.v;
}
int lowbit(int x) {
return x&(-x);
}
//设原始矩阵为a,将a[i]加上val时对c所做的修改
void update(int i, int val) {
while (i <= n) {
c[i].id += val;
i += lowbit(i);
}
}
void add(int i,int val) {
while(i <= n) {
c[i].sum += (1LL) * val;
i += lowbit(i);
}
}
int get_sumid(int i) {
int sum = 0;
while(i > 0) {
sum += c[i].id;
i -= lowbit(i);
}
return sum;
}
//求前i项元素的和
int get_sum(int i) {
int sum=0;
while (i > 0) {
sum += c[i].sum;
i -= lowbit(i);
}
return sum;
}
int main() {
while(scanf("%d",&n) == 1) {
clear();
//先离散操作
for(int i=1;i<=n;i++) {
scanf("%d",&p[i].v);
a[i] = p[i].v;
p[i].id = i;//循环序号必须从1开始
}
sort(p + 1,p + n + 1,cmp);
for(int i=1;i<=n;i++)
aa[p[i].id] = i;//aa数组存了原来大小信息
LL ans = 0;
for(int i=1;i<=n;i++) {
update(aa[i],1);
add(a[i],a[i]);
int ans1 = i - get_sumid(aa[i]);//i代表当前已经插入的个数,ge_sum(aa[i])代表比aa[i]小的数个数,减去即为大的个数,即逆序数
if(ans1 != 0) {
LL ans2 = (1LL) * get_sum(n) - (1LL) * get_sum(a[i]);
ans += (1LL) * ans1 * a[i] + ans2;
}
}
printf("%I64d\n",ans);
}
return 0;
}
AC代码:
#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#include<cctype>
#define ll long long
#define LL __int64
#define eps 1e-8
//const ll INF=9999999999999;
#define inf 0xfffffff
using namespace std;
//vector<pair<int,int> > G;
//typedef pair<int,int> P;
//vector<pair<int,int>> ::iterator iter;
//
//map<ll,int>mp;
//map<ll,int>::iterator p;
const int N = 500000 + 10;
int n;
typedef struct C {
LL sum;
int id;
};
C c[N];
void clear() {
memset(c,0,sizeof(c));
}
int lowbit(int x) {
return x&(-x);
}
//设原始矩阵为a,将a[i]加上val时对c所做的修改
void update(int i, int val) {
int j = i;
while (i <= n) {
c[i].id += val;
c[i].sum += j;
i += lowbit(i);
}
}
int get_sumid(int i) {
int sum = 0;
while(i > 0) {
sum += c[i].id;
i -= lowbit(i);
}
return sum;
}
//求前i项元素的和
LL get_sum(int i) {
LL sum=0;
while (i > 0) {
sum += c[i].sum;
i -= lowbit(i);
}
return sum;
}
int main() {
while(scanf("%d",&n) == 1) {
clear();
LL ans = 0;
for(int i=1;i<=n;i++) {
int x;
scanf("%d",&x);
update(x,1);
LL ans1 = i - get_sumid(x);//i代表当前已经插入的个数,ge_sum(aa[i])代表比aa[i]小的数个数,减去即为大的个数,即逆序数
if(ans1 != 0) {
LL ans2 = get_sum(n) - (1LL) * get_sum(x);
ans += ans1 * x + ans2;
}
}
printf("%I64d\n",ans);
}
return 0;
}
/*
4
1 3 2 4
5
1 5 3 2 4
5
5 4 3 2 1
7
3 4 5 1 2 7 6
6
2 1 6 5 4 3
7
4 3 6 5 2 1 7
ans:
5
29
60
46
57
69
*/