Codeforces Round #212 (Div. 2) C. Insertion Sort
Petya is a beginner programmer. He has already mastered the basics of the C++ language and moved on to learning algorithms. The first algorithm he encountered was insertion sort. Petya has already written the code that implements this algorithm and sorts the given integer zero-indexed array a of size n in the non-decreasing order.
for (int i = 1; i < n; i = i + 1)
{
int j = i;
while (j > 0 && a[j] < a[j - 1])
{
swap(a[j], a[j - 1]); // swap elements a[j] and a[j - 1]
j = j - 1;
}
}
Petya uses this algorithm only for sorting of arrays that are permutations of numbers from 0 to n - 1. He has already chosen the permutation he wants to sort but he first decided to swap some two of its elements. Petya wants to choose these elements in such a way that the number of times the sorting executes function swap, was minimum. Help Petya find out the number of ways in which he can make the swap and fulfill this requirement.
It is guaranteed that it's always possible to swap two elements of the input permutation in such a way that the number of swap function calls decreases.
The first line contains a single integer n (2 ≤ n ≤ 5000) — the length of the permutation. The second line contains n different integers from 0 to n - 1, inclusive — the actual permutation.
Print two integers: the minimum number of times the swap function is executed and the number of such pairs (i, j) that swapping the elements of the input permutation with indexes i and j leads to the minimum number of the executions.
5
4 0 3 1 2
3 2
5
1 2 3 4 0
3 4
In the first sample the appropriate pairs are (0, 3) and (0, 4).
In the second sample the appropriate pairs are (0, 4), (1, 4), (2, 4) and (3, 4).
题意:给出n个数,范围0到n-1,然后给出一个插入排序的代码,可以交换两个数,然后使交换后的排列使用交换函数的次数最少,然后问交换后的排列的调用交换函数最少次数是多少
和能有几个索引对交换可以的到最少
思路:首先它的范围只有5000,然后我们看到那个插入排序想想,他只有前面大于后面的就要交换一次,所以没交换的时候的次数其实就是整个排列的逆序数,然后我们其实考虑的就是
交换一个索引使得他的逆序对个数减少最多,然后求有几个这样的索引即可,逆序数这部分我们可以使用树状数组求,我们枚举每个索引,只有前面这个数大于后面的时候我们才要考虑
是否要交换
给出一个例子
4 5 0 2 3 7 1
然后我们当前访问的索引对是(0, 7)-〉4 1
然后我们如何计算4 1交换后能减少多少个逆序对呢
首先我们如果交换 4 1的话 中间那些比4大的数的逆序对肯定不会改变,因为这些数都是大于4的,我把1 4交换,4还是小于那些数,这些逆序对就不会改变了
小于1的数也不用考虑,因为例子中的4 1交换,中间那个0还是小于1,逆序对还是存在,所以并 没有改变
所以我们只要考虑那些小于4大于1的数(a[j]<x<a[i])
我们用树状数组来优化处理
把中间小于4的数都入树状数组
然后是1的时候,我们找出大于1的数有多少然后我们可以找到2 3这两个数
然后我们把4 和1交换之后,中间那些小于4大于1的数因为大于他们的4到了后面,他们的逆序对都-1,还有1移到了2 3这些数前面,所以又要减去这么多逆序对数
总的就是 a[j]<x<a[i] 的两倍
#include<cstdio>
#include<cstring>
using namespace std;
int n,a[];
int f[];
int lowbit(int x)
{
return x&(-x);
}
int add(int x)
{
while(x)
{
f[x]++;
x-=lowbit(x);
}
}
int query(int x)
{
int sum=;
while(x<=n)
{
sum+=f[x];
x+=lowbit(x);
}
return sum;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]++;
}
int s=;
int mx=,cs=;
for(int i=;i<=n;i++)
{
memset(f,,sizeof(f)); //把之前树状数组的数清空
for(int j=i+;j<=n;j++)
{
if(a[i]>a[j])
{
s++;//存的是总的逆序对个数
int num=+*query(a[j]);//求得能减去的逆序对个数,+1是因为当前还没有入树状数组
if(num>mx)//大于更新
{
mx=num;
cs=;
}
else if(num==mx) //等于得时候说明索引对又新加了一对
{
cs++;
}
add(a[j]);
}
}
}
printf("%d %d",s-mx,cs);
}
Codeforces Round #212 (Div. 2) C. Insertion Sort的更多相关文章
- 贪心/数学 Codeforces Round #212 (Div. 2) A. Two Semiknights Meet
题目传送门 /* 贪心/数学:还以为是BFS,其实x1 + 4 * k = x2, y1 + 4 * l = y2 */ #include <cstdio> #include <al ...
- Codeforces Round #486 (Div. 3)-B. Substrings Sort
B. Substrings Sort time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Codeforces Round #648 (Div. 2) B. Trouble Sort
一开始读错题了...想当然地认为只能相邻元素交换...(然后换了两种写法WA了4发,5分钟切A的优势荡然无存) 题目链接:https://codeforces.com/contest/1365/pro ...
- Codeforces Round #198 (Div. 2) D. Bubble Sort Graph (转化为最长非降子序列)
D. Bubble Sort Graph time limit per test 1 second memory limit per test 256 megabytes input standard ...
- Codeforces Round #650 (Div. 3) F1. Flying Sort (Easy Version) (离散化,贪心)
题意:有一组数,每次操作可以将某个数移到头部或者尾部,问最少操作多少次使得这组数非递减. 题解:先离散化将每个数映射为排序后所对应的位置,然后贪心,求最长连续子序列的长度,那么最少的操作次数一定为\( ...
- Codeforces Round #212 (Div. 2) D. Fools and Foolproof Roads 并查集+优先队列
D. Fools and Foolproof Roads You must have heard all about the Foolland on your Geography lessons. ...
- Codeforces Round 212 Div 2 报告(以前没写完,现在也没心情补了,先就这样吧)
A. Two Semiknights Meet 题目大意:有一个8x8的棋盘,上面放有两个骑士,骑士以“田字”的方式走.每个方格都被定义为good或者bad,问骑士能否在good的格子中相遇? 由于骑 ...
- Codeforces Round #258 (Div. 2) 小结
A. Game With Sticks (451A) 水题一道,事实上无论你选取哪一个交叉点,结果都是行数列数都减一,那如今就是谁先减到行.列有一个为0,那么谁就赢了.因为Akshat先选,因此假设行 ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
随机推荐
- 全站从http升级到https(WordPress博客)
最近几年HTTPS取代HTTP已经成为大趋势,HTTP是超文本传输协议,信息是明文传输的,而HTTPS是安全超文本传输协议,需要证书和提供安全连接,换句话说,HTTPS是嵌套了SSL加密的HTTP连接 ...
- CPU型号各个字母的含义
CPU 型号的含义 首先介绍 4 个数字的含义(以 i7-3540M) 第一位 3540M 中的 "3"代表:代, 3 表示第三代 第二位 3540M 中的 "5&quo ...
- 正睿 2018 提高组十连测 Day4 T3 碳
记'1'为+1,'0'为-1; 可以发现 pre[i],suf[i]分别为前/后缀和 a[i]=max(pre[l.....i]); b[i]=max(suf[i+1....r]); ans=max( ...
- HDU-6336-构造
Problem E. Matrix from Arrays Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 ...
- Oracle 11.2.0.4.0 Dataguard部署和日常维护(3)-Datauard监控篇
1. v$database 查看当前数据库的角色和保护模式 primary库查看 column NAME format a10 column PROTECTION_MODE format a2 ...
- Spring Boot系列之配置日志输出等级
我们都知道Spring boot 默认使用 logback作进行日志输出,那么 在配置Spring boot日志输出时有两种方式: 通过application.properties 配置文件的方式来配 ...
- Async:简洁优雅的异步之道
前言 在异步处理方案中,目前最为简洁优雅的便是 async函数(以下简称A函数).经过必要的分块包装后,A函数能使多个相关的异步操作如同同步操作一样聚合起来,使其相互间的关系更为清晰.过程更为简洁.调 ...
- django学习之——模版
为了减少模板加载调用过程及模板本身的冗余代码,Django 提供了一种使用方便且功能强大的 API ,用于从磁盘中加载模板, 要使用此模板加载API,首先你必须将模板的保存位置告诉框架. 设置的保存文 ...
- Windows下安装 Memcache
1.下载Memcached Windows服务端程序.(memcached >= 1.4.5 版本安装32 32位系统 1.4.5版本:http://static.runoob.com/down ...
- [LeetCode] 110. Balanced Binary Tree ☆(二叉树是否平衡)
Balanced Binary Tree [数据结构和算法]全面剖析树的各类遍历方法 描述 解析 递归分别判断每个节点的左右子树 该题是Easy的原因是该题可以很容易的想到时间复杂度为O(n^2)的方 ...