线段树(3)(hdu1394)
来源:互联网 发布:新顶级域名投资 编辑:程序博客网 时间:2024/05/18 02:06
hdu1394 Minimum Inversion Number
http://acm.hdu.edu.cn/showproblem.php?pid=1394
本来想和其他博客合在一起,但是这道题给了我很多启发和感想,一并写下来,纪念我过去一星期的颓废。最近一直很浮躁,在寝室怎么也想不进去题目,一直西看看,东看看。下星期开始做编译原理作业了,TMD还有一个信安比赛,还要期中考试,时间很紧张。
这道题应该很早就有想法了,直到昨天晚上才敲完,但是一直WA,换了一种查询方法,AC了,早上起来,加了一行代码,原先WA的做法AC了。两种查询一并写了下来(用了条件编译,条件编译也是利器)。题意大概是给一个数列,求出逆序数,然后将数列第一个数移到最后形成一个新的数列,然后求出逆序数,一直循环这种做法,求出最小逆序数。解法是:先用线段树求出第一个数列的逆序数(树状数组也可以哈)sum。对于移到最后的那个数a[i],比他大的n-a[i],比他小的有a[i]-1,那么逆序数增加n-a[i],减少a[i]-1。依次求n-1次。更新最小值;
#include <stdio.h>#include <algorithm>#define DD 1using namespace std;const int MAX = 5000 + 10;int n, num[MAX];struct node{ int l; int r; int cnt;}a[MAX<<2];void pushup(int pos){ a[pos].cnt = a[pos<<1].cnt + a[pos<<1|1].cnt;}void build(int l, int r, int pos){ a[pos].l = l; a[pos].r = r; a[pos].cnt = 0; if (l == r) { return; } int mid = (l+r)>>1; build(l, mid, pos<<1); build(mid+1, r, pos<<1|1);}void update(int goal, int pos){ if (a[pos].l == a[pos].r) { a[pos].cnt ++; return; } int mid = (a[pos].l + a[pos].r) >> 1; if (goal<=mid) { update(goal, pos<<1); } else { update(goal , pos<<1|1); } pushup(pos);}#if DDint query(int goal, int pos){if (a[pos].l == a[pos].r){return a[pos].cnt;} int mid = (a[pos].l + a[pos].r) >> 1; if (goal < mid) { return query(goal, pos<<1) + a[pos<<1|1].cnt; } else if (goal > mid) { return query(goal, pos<<1|1); } else { return a[pos<<1|1].cnt; }}#elseint query(int l, int r, int pos){ if (a[pos].l == l && a[pos].r == r) { return a[pos].cnt; } int mid = (a[pos].l + a[pos].r)>>1; if (r<=mid) { return query(l, r, pos<<1); } else if (l > mid) { return query(l, r, pos<<1|1); } else { return query(l, mid, pos<<1) + query(mid+1, r, pos<<1|1); }}#endifint main(){ int i, sum, ans; while (scanf("%d", &n) == 1) { ans = 0; sum = 0; build(1, n, 1); for (i=1; i<=n;i++) { scanf("%d", num+i); num[i]++; #if DD //printf("%d\n", query(num[i], 1)); sum += query(num[i], 1); #else //printf("%d\n", query(num[i], n, 1)); sum += query(num[i],n, 1); #endif update(num[i], 1); } ans = sum; for (i=1; i<n; i++) { sum = sum - num[i] + 1 + n - num[i]; ans = min(ans, sum); } printf("%d\n", ans); } return 0;}
- 线段树(3)(hdu1394)
- hdu1394 (逆序数,暴力,线段树)
- hdu1394-Minimum Inversion Number(线段树)
- hdu1394 Minimum Inversion Number(线段树)
- HDU1394 Minimum Inversion Number(线段树)
- HDU1394:Minimum Inversion Number(线段树)
- hdu1394(线段树求逆序对数)
- 线段树求逆序数(hdu1394)
- hdu1394(最小逆序数)(线段树单点更新)
- hdu1394——线段树(单点更新 区间求和)
- HDU1394-Minimum Inversion Number(线段树单点更新)
- 数据结构 线段树 hdu1394 Minimum Inversion Number(单点更新)
- hdu1394 -Minimum Inversion Number(线段树求逆序数)
- HDU1394 Minimum Inversion Number(线段树单点更新)
- hdu1394~线段树求和
- hdu1394之线段树详解
- HDU1394线段树单点更新
- hdu1394 线段树 / 树状数组
- MFC对话框程序屏蔽ESC和ENTER键退出
- component must be showing on the screen to determine its location
- “Visual Studio Help Downloader Plus” & “Visual Studio 2010 Help Downloader Plus”官网
- 在myeclipse 启动tomcat出错解决
- PCB 名词解释
- 线段树(3)(hdu1394)
- error: cannot find -ldemo_shared
- java中遍历一个对象的所有属性
- 缩小MS SQL数据库日志文件
- FreeBSD通过PORTS安装软件的几个常用命令
- 职业成功的十五条法则
- android 增加三方库
- Choices
- javascript特效收藏经典