这题目意思非常easy,就是给你一个数组,然后让你又一次排好序,排序有要求的,每次仅仅能交换两个元素的位置,交换须要一个代价 就是两个元素之和,问你把数组重小到大排好最少须要多少代价





可能一開始想不到逆序数,我是专门做专题往那边想才想到的,举个样例吧

数组: 9 1 0 5 4

此时到 0 的时候,我们先手写一下最小代价,然后再依照自己的推測去看看,就是当前扫到0,那么前面比它大的数有2个,所以先 部分代价为 2 * 0,然后再加上前面比它大的数 也就是9 和1 ,那么最小代价为10,发现跟手算的一样,那么 再多试几个 最后我们就发现了





对于当前数num,前面有x个比它大的数,那么走到当前一步的 最小代价为 x*num 再加上前面比它大的数之和





这样就非常easy跟树状数组扯上关系了,当前一步的逆序数 事实上就是  前面比它大的数的个数,然后同一时候又能用树状数组对于前面比它大的数求和,这样问题就完美攻克了,一開始我看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
*/



HDU2838 Cow Sorting 树状数组 区间求和加逆序数的应用的更多相关文章

  1. hdu 1754 I Hate It(树状数组区间求最值)2007省赛集训队练习赛(6)_linle专场

    题意: 输入一行数字,查询第i个数到第j个数之间的最大值.可以修改其中的某个数的值. 输入: 包含多组输入数据. 每组输入首行两个整数n,m.表示共有n个数,m次操作. 接下来一行包含n个整数. 接下 ...

  2. hdu 2838 Cow Sorting 树状数组求所有比x小的数的个数

    Cow Sorting Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  3. hdu 2838 Cow Sorting (树状数组)

    Cow Sorting Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. LG5200 「USACO2019JAN」Sleepy Cow Sorting 树状数组

    \(\mathrm{Sleepy Cow Sorting}\) 问题描述 LG5200 题解 树状数组. 设\(c[i]\)代表\([1,i]\)中归位数. 显然最终的目的是将整个序列排序为一个上升序 ...

  5. HDU3874 /HDU3333 树状数组 区间求不重复数和

    Necklace Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  6. HDU Cow Sorting (树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2838 Cow Sorting Problem Description Sherlock's N (1  ...

  7. HDU 6318 Swaps and Inversions 思路很巧妙!!!(转换为树状数组或者归并求解逆序数)

    Swaps and Inversions Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  8. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) E. Cards Sorting 树状数组

    E. Cards Sorting time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  9. hdu 4638 树状数组 区间内连续区间的个数(尽可能长)

    Group Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

随机推荐

  1. POJ 3286 How many 0's(数位DP模板)

    题目链接:http://poj.org/problem?id=3286 题目大意: 输入n,m,求[n,m]的所有数字中,0出现的总数是多少,前导零不算. 解题思路: 模板题,设dp[pos][num ...

  2. HDU 3068 最长回文(manacher模板题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题目大意:求字符串s中最长的回文子串 解题思路:manacher模板 代码 #include&l ...

  3. C++之插入迭代器

    #include<iostream> #include<vector> #include<list> #include<iterator> usingn ...

  4. The Art Of Computer Programming: 1.1

    The Art Of Computer Programming: 1.1 */--> div.org-src-container { font-size: 85%; font-family: m ...

  5. CentOS6.9 安装OpenResty

    1.安装依赖包 yum install -y gcc gcc-c++ readline-devel pcre-devel openssl-devel tcl perl 2.安装OpenResty 首先 ...

  6. C#基础系列 - 抽象类及其方法的学习

    在C#中使用关键字 abstract 来定义抽象类和抽象方法. 不能初始化的类被叫做抽象类,它们只提供部分实现,但是另一个类可以继承它并且能创建它们的实例. "一个包含一个或多个纯虚函数的类 ...

  7. Android IntentService

    IntentService简要分析 IntentService 继承自 android.app.Service.内部实现极其简单. 首先在 onCreate()中去开启了一个 HandlerThrea ...

  8. odoo 模型与ORM

    型号属性 在/模型添加activity.py文件 class ActivityEvent(models.Model): _name = 'activity.event' _inherit = 'eve ...

  9. 50个必备jQuery代码段

    0. 如何创建嵌套的过滤器: 1 2 3 4 5 //允许你减少集合中的匹配元素的过滤器, //只剩下那些与给定的选择器匹配的部分.在这种情况下, //查询删除了任何没(:not)有(:has) // ...

  10. 1008 Elevator (20)(20 point(s))

    problem The highest building in our city has only one elevator. A request list is made up with N pos ...