【bzoj4240】有趣的家庭菜园 贪心+树状数组
题目描述
输入
输出
样例输入
6
2
8
4
5
3
6
样例输出
3
题解
贪心+树状数组
一个结论:交换后形成的以原来位置为元素的序列的逆序对数为最小交换次数
举个例子:原来的数是1000 100 10 1,交换后形成了1 100 1000 10,则最小交换次数为4 2 1 3的逆序对数4。
那么根据这个结论,在这道题中,如果每个数都不相等,那么从小到大枚举每个数,它对答案的贡献是剩下的数中与它形成逆序对的数的个数,即位置比它大的数的个数和位置比它小的数的个数。
于是我们可以开两个树状数组,分别维护比一个数的位置大的数的个数和比一个数的位置小的数的个数,查询时对于两者取一个最小值即为答案。最后再把该数删除。
但是这样做可能会WA,因为可能存在相同的数。此时我们考虑:相同的数也一定是互不影响的,否则不会成为最优答案。于是我们可以先把相同的数删除掉,再进行查询即可。
#include <cstdio>
#include <algorithm>
#define N 300010
using namespace std;
struct data
{
int v , id;
}a[N];
int f1[N] , f2[N] , n;
bool cmp(data a , data b)
{
return a.v < b.v;
}
void add(int x , int a)
{
int i;
for(i = x ; i <= n ; i += i & -i) f1[i] += a;
for(i = x ; i ; i -= i & -i) f2[i] += a;
}
int query(int x)
{
int i , ans1 = 0 , ans2 = 0;
for(i = x ; i ; i -= i & -i) ans1 += f1[i];
for(i = x ; i <= n ; i += i & -i) ans2 += f2[i];
return min(ans1 , ans2);
}
int main()
{
int i , j;
long long ans = 0;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i].v) , a[i].id = i , add(i , 1);
sort(a + 1 , a + n + 1 , cmp);
for(i = 1 ; i <= n ; i = j)
{
for(j = i ; a[j].v == a[i].v ; j ++ ) add(a[j].id , -1);
for(j = i ; a[j].v == a[i].v ; j ++ ) ans += query(a[j].id);
}
printf("%lld\n" , ans);
return 0;
}
【bzoj4240】有趣的家庭菜园 贪心+树状数组的更多相关文章
- [BZOJ4240]有趣的家庭菜园(贪心+树状数组)
最后数列一定是单峰的,问题就是最小化最后的位置序列的逆序对数. 从大到小加数,每次贪心看放左边和右边哪个产生的逆序对数更少,树状数组即可. 由于大数放哪对小数不产生影响,所以正确性显然. 注意相同数之 ...
- [bzoj4240]有趣的家庭菜园_树状数组
有趣的家庭菜园 题目链接:https://lydsy.com/JudgeOnline/problem.php?id=4240 数据范围:略. 题解: 第一步比较简单,只需要排序之后,每个数不是在左边就 ...
- bzoj 4240: 有趣的家庭菜园【树状数组+贪心】
以为是逆序对数-- 实际上,原数组移动若干次后我们会得到一个新的下标序列,需要的移动次数是这个新下标序列的逆序对数 然后我们要让这个最小,考虑贪心先按h把下标排一遍序,然后每次询问到一种值的时候,对每 ...
- bzoj4240: 有趣的家庭菜园(树状数组+贪心思想)
4240: 有趣的家庭菜园 题目:传送门 题解: 好题!%%% 一开始不知道在想什么鬼,感觉满足二分性?感觉可以维护一个先单调增再单调减的序列? 然后开始一顿瞎搞...一WA 看一波路牌...树状数组 ...
- [bzoj4240] 有趣的家庭菜园
还是膜网上题解QAQ 从低到高考虑,这样就不会影响后挪的草了. 每次把草贪心地挪到代价较小的一边.位置为i的草,花费为min( 1..i-1中更高的草的数目,i+1..n中更高的草的数目 ) 因为更小 ...
- gym 102082G BZOJ4240 贪心+树状数组
4240: 有趣的家庭菜园 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 756 Solved: 349[Submit][Status][Discu ...
- 贪心+树状数组维护一下 Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) D
http://codeforces.com/contest/724/problem/D 题目大意:给你一个串,从串中挑选字符,挑选是有条件的,按照这个条件所挑选出来的字符集合sort一定是最后选择当中 ...
- D 洛谷 P3602 Koishi Loves Segments [贪心 树状数组+堆]
题目描述 Koishi喜欢线段. 她的条线段都能表示成数轴上的某个闭区间.Koishi喜欢在把所有线段都放在数轴上,然后数出某些点被多少线段覆盖了. Flandre看她和线段玩得很起开心,就抛给她一个 ...
- [P4064][JXOI2017]加法(贪心+树状数组+堆)
题目描述 可怜有一个长度为 n 的正整数序列 A,但是她觉得 A 中的数字太小了,这让她很不开心. 于是她选择了 m 个区间 [li, ri] 和两个正整数 a, k.她打算从这 m 个区间里选出恰好 ...
随机推荐
- 《深入理解JavaScript闭包和原型》笔记
By XFE-堪玉 以下知识来源于对王福朋所写<深入理解javascript原型和闭包>的理解和整理 一切都是对象[引用类型],对象都是通过函数创建的[Funcion类型] 对象是属性的集 ...
- win10 64位 mysql安装过程出现status显示failed
mysql安装过程出现status显示failed,如下图: 由于我的电脑是64位系统,这里需要升级一个插件,即32位 visual C++ 2013 and visual C++ redistri ...
- MySQL优化汇总
1)mysql优化汇总,转载自网络
- Monkey安装和使用介绍
安装步骤1)安装sdk环境在系统环境变量中配置 ANDROID_HOMED:\sdk PATH%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools;%A ...
- Dijkstra算法——单源最短路算法
一.介绍 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他各个节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 适用于有 ...
- webpack devserver的说明
一般我们在项目中 如果用webpack的话,基本都会用到webpack-dev-server,配置大致如下: devServer={ contentBase: basePath, historyApi ...
- js parse_url 引发的
原文链接:https://www.w3.org/TR/2011/WD-html5-20110525/origin-0.html 这里只是做下记录: 5.3 Origin — HTML5 li, dd ...
- tomcat BIO 、NIO 、AIO
11.11活动当天,服务器负载过大,导致部分页面出现了不可访问的状态.那后来主管就要求调优了,下面是tomcat bio.nio.apr模式以及后来自己测试的一些性能结果. 原理方面的资料都是从网上找 ...
- c语言产生随机数的方法
在C语言中,rand()函数可以用来产生随机数,但是这不是真真意义上的随机数,是一个伪随机数,是根据一个数,我们可以称它为种子,为基准以某个递推公式推算出来的一系数,当这系列数很大的时候,就符合正态公 ...
- ajax实现上传图片保存到后台并读取
上传图片有两种方式: 1.fileReader 可以把图片解析成base64码的格式,简单粗暴 2.canvas 可以重新绘制一张图片,可以先把获取得到的图片的blob放进canvas里面,再生成 ...