HDU 4911 (树状数组)
2016-07-07 22:50
387 查看
题目连接:点击这里
题意:给出一个序列, 交换某些相邻的数, 求剩下逆序对最少的个数。
显然一次交换可以减少一个逆序对, 所以离散化一下树状数组一下求出最大的逆序对减去交换次数即可。trick是判断交换次数比逆序对大的情况。
#include <bits/stdc++.h> using namespace std; #define maxn 100005 int n, k; map <int, int> gg; vector <int> num; struct node { int num, id; }a[maxn]; int c[maxn]; int lowbit (int x) { return x&(-x); } void add (int pos) { for (int i = pos; i <= n; i += lowbit (i)) { c[i]++; } } int sum (int pos) { int ans = 0; for (int i = pos; i >= 1; i -= lowbit (i)) { ans += c[i]; } return ans; } bool cmp1 (const node &a, const node &b) { return a.num > b.num || (a.num == b.num && a.id > b.id); } void lisanhua () { gg.clear (); sort (num.begin (), num.end ()); int cnt = 0; for (int i = 0; i < n; i++) { if (!i || num[i] != num[i-1]) gg[num[i]] = ++cnt; } for (int i = 1; i <= n; i++) a[i].num = gg[a[i].num]; } int main () { while (scanf ("%d%d", &n, &k) == 2) { num.clear (); for (int i = 1; i <= n; i++) { scanf ("%d", &a[i].num); num.push_back (a[i].num); a[i].id = i; } lisanhua (); sort (a+1, a+1+n, cmp1); memset (c, 0, sizeof c); long long ans = 0; for (int i = 1; i <= n; i++) { ans += sum (a[i].id); add (a[i].id); } if (ans-k <= 0) { printf ("0\n"); } else printf ("%lld\n", ans-k); } return 0; }
相关文章推荐
- hibernate的实体生命周期
- http 协议 与tcp/ip协议、Socket的区别
- leetcode: LRU Cache
- Activity与Service用Messenger通信
- 19. Remove Nth Node From End of List
- 焦点冲突处理例子
- BAV99的ESD保护作用解析
- Unity3D所使用的第三方工具
- 【我的《冒号课堂》学习笔记】设计原则(4)保变原则
- 《互联网+医疗》,资料汇编,主要的事件都是2013、2014年的事,二星
- 黄聪:WordPress后台添加侧边栏菜单(WP教程add_menu_page)
- SDAU练习四1006
- EditPlus快捷键
- LooCI
- hibernate关联关系
- 获得 LayoutInflater 实例的三种方式
- MySql基本命令
- Qt 实现窗口置顶与取消置顶
- 提高项目26.1-查成绩
- ios9使用自签名ssl -9824 -9801