[hdu4911]逆序对相关

思路:由于只能交换相邻的数,所以每次最多减小1个逆序对(且如果存在逆序对那么肯定可以减小1个)!于是乎。。就是统计逆序对的裸题了。树状数组或归并都行。

 1 #pragma comment(linker, "/STACK:10240000,10240000")
 2
 3 #include <iostream>
 4 #include <cstdio>
 5 #include <algorithm>
 6 #include <cstdlib>
 7 #include <cstring>
 8 #include <map>
 9 #include <queue>
10 #include <deque>
11 #include <cmath>
12 #include <vector>
13 #include <ctime>
14 #include <cctype>
15 #include <set>
16
17 using namespace std;
18
19 #define mem0(a) memset(a, 0, sizeof(a))
20 #define lson l, m, rt << 1
21 #define rson m + 1, r, rt << 1 | 1
22 #define define_m int m = (l + r) >> 1
23 #define Rep(a, b) for(int a = 0; a < b; a++)
24 #define lowbit(x) ((x) & (-(x)))
25 #define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
26 #define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
27 #define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
28
29 typedef double db;
30 typedef long long LL;
31 typedef pair<int, int> pii;
32 typedef multiset<int> msi;
33 typedef multiset<int>::iterator msii;
34 typedef set<int> si;
35 typedef set<int>::iterator sii;
36 typedef vector<int> vi;
37
38 const int dx[8] = {1, 0, -1, 0, 1, 1, -1, -1};
39 const int dy[8] = {0, -1, 0, 1, -1, 1, 1, -1};
40 const int maxn = 1e5 + 7;
41 const int maxm = 1e5 + 7;
42 const int maxv = 1e7 + 7;
43 const int MD = 1e9 +7;
44 const int INF = 1e9 + 7;
45 const double PI = acos(-1.0);
46 const double eps = 1e-10;
47
48 int tmp[maxn], a[maxn];
49
50 LL merge(int l, int m, int r) {
51     int p = m + 1, t = l;
52     LL res = 0;
53     for (int i = l; i <= m; i++) {
54         while (p <= r && a[i] > a[p]) {
55             tmp[t++] = a[p++];
56         }
57         res += p - m - 1;
58         tmp[t++] = a[i];
59     }
60     for (int i = l; i < p; i++) a[i] = tmp[i];
61     return res;
62 }
63
64 LL merge_sort(int l, int r) {
65     if (l == r) return 0;
66     define_m;
67     return merge_sort(l, m) + merge_sort(m + 1, r) + merge(l, m, r);
68 }
69
70 int main() {
71     //freopen("in.txt", "r", stdin);
72     int n;
73     LL k;
74     while (cin >> n >> k) {
75         for (int i = 0; i < n; i++) {
76             scanf("%d", a + i);
77         }
78         LL ans = merge_sort(0, n - 1) - k;
79         ans = max(ans, 0LL);
80         cout << ans << endl;
81     }
82     return 0;
83 }

Hint:做这题的时候发现一个不容易发现的坑(与这题本身无关),多个函数相加并不一定按从左至右的顺序执行(可能是为了某种意义上地优化代码)。此代码用c++交好像w会a掉,不信可以一试~(c++貌似优化程度比较高?)

时间: 2025-01-05 00:05:54

[hdu4911]逆序对相关的相关文章

求逆序对(inversion)的个数

2-4 逆序对 设A[1...n]是一个包含n个不同数的数组,如果在i<j的情况下,有A[i]>A[j],则(i,j)就称为A中的一个逆序对(inversion). a)列出数组<2, 3, 8, 6, 1>的5个逆序对 b)如果数组的元素取自集合{1,2,...,n}, 那么, 怎样的数组含有最多的逆序对?它包含多少个逆序对? c)插入排序的运行时间与输入数组中逆序对的数量之间有怎样的关系?说明你的理由. d)给出一个算法,它能用Θ(nlgn)的最坏情况运行时间,确定n个元素的任

归并排序及统计数组逆序对

 1.归并排序 <算法导论>P19 参考网址: 白话经典算法系列之五 归并排序的实现 - MoreWindows Blog - 博客频道 - CSDN.NET http://blog.csdn.net/morewindows/article/details/6678165 #include "stdafx.h" #include <iostream> using std::cout; #define ARRAY_LENGTH 11 //排序两个已经排好序的数

剑指Offer 面试题36:数组中的逆序对及其变形(Leetcode 315. Count of Smaller Numbers After Self)题解

剑指Offer 面试题36:数组中的逆序对 题目:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 例如, 在数组{7,5,6,4}中,一共存在5个逆序对,分别是(7,6),(7,5),(7,4),(6,4)和(5,4),输出5. 提交网址: http://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=13&tqId=11188 或 htt

codeforces 414C C. Mashmokh and Reverse Operation(归并排序求逆序对)

题目链接: C. Mashmokh and Reverse Operation time limit per test 4 seconds memory limit per test 512 megabytes input standard input output standard output Mashmokh's boss, Bimokh, didn't like Mashmokh. So he fired him. Mashmokh decided to go to university

求逆序对(线段树版)

一个序列a1,a2,a3...aN,求出满足:ai > aj 且 i < j 的个数. 一个最容易想到的方法就是枚举所有的i,j看看是否满足,显然是O(n^2)的复杂度.不够好. 可以这样考虑,开一个数组保存这n个数出现的位置和对应的次数,这个数组要开到a数组里最大的那个数MAX,也就是hash,初始状态数组里没有元素,每个数对应的个数都是0. 如果考虑第i个数,找到比它大的所有的数 的个数,查找的范围即 ai+1~MAX,这就是到i这个位置的逆序对的总和,接着把a[i]这个数添加到数组里,也

剑指offer: 数组中的逆序对

1. 最简单的思路,对每个值,遍历与其逆序的数组对:但时间复杂度太高: 2. 归并排序的思路: 先将数组分隔成子数组,先统计出子数组内的逆序对的数目,然后统计两个相邻子数组之间的逆序对的数目: int InversePairsCore(int *data, int * copy, int start, int end) { //递归介绍条件,只剩一个元素 if(start==end) { copy[start]=data[start]; return 0; } int length=(end-s

[HAOI2009]逆序对数列

题目描述 对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数.那么逆序对数为k的这样自然数数列到底有多少个? 输入输出格式 输入格式: 第一行为两个整数n,k. 输出格式: 写入一个整数,表示符合条件的数列个数,由于这个数可能很大,你只需输出该数对10000求余数后的结果. 输入输出样例 输入样例#1: 4 1 输出样例#1: 3 说明 样例说明: 下列3个数列逆序对数都为1:分别是1 2

bzoj3295动态逆序对

Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 5362  Solved: 1814[Submit][Status][Discuss] Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数. Input 输入第一行包含两个整数n和m,即初始元素的个数和删除的元素个数

【bzoj3295】动态逆序对

我怎么控制不住自己又写了个数据结构啊--真是的-- 其实我是想练CDQ分治的--结果忍不住又写了个主席树. 首先看看不动态的逆序对咋做?树状数组嘛. 那么删除咋搞?就是考虑贡献,把它前面比他大的,后面比他小的减去-- 诶?带修改主席树?我--我好像才写过--? 1 #include<bits/stdc++.h> 2 #define inf 0x7fffffff 3 #define N 100005 4 #define M 5000005 5 using namespace std; 6 typ