hdu 1394 Minimum Inversion Number(线段树 单点更新)
来源:互联网 发布:java微信客服接口开发 编辑:程序博客网 时间:2024/05/20 12:50
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1394
题目大意:
给由0-n-1这n个数构成的n个数,定义一个逆序数(前面的比后面的大的数的个数)。把第一个数移到最后的位置,得到一个新的序列,得到一个新的逆序数。一共可以移动n-1次,得到n个逆序数,问这n个逆序数最小的是多少。
解题思路:
1、先求出第一个序列的逆序数。
根据题目特点,建立一个0——(n-1)的线段树,每个区间保存含有当前区间内数的个数。
对每一个数,查找该数到n-1内已存在数的个数,(因为该数前面的所有数都压到线段树里面去了),再把该数压进去。
把每个数前面的逆序数加起来,就可以构造出整个逆序数。
2、当把第一个移到最后时,后面有0——(save[1]-1)一共save[1]个数比save[i]小,共有n-1-save[1]个数比save[1]大
所以得到递推公式,sum=sum-save[i]+(n-1-save[i])。
代码:
#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<stack>#include<queue>#define eps 1e-6#define INF (1<<20)#define PI acos(-1.0)using namespace std;#define lson l,m,rt<<1#define rson m+1,r,(rt<<1)|1#define maxn 5100int sum[4*maxn],save[maxn];void build(int l,int r,int rt){ sum[rt]=0; //表示该区间一共有多少个数 if(l==r) return ; int m=(l+r)>>1; build(lson); build(rson); return ;}int query(int L,int R,int l,int r,int rt){ if(L<=l&&R>=r) //如果要找区间大于当前区间,直接返回当前区间 return sum[rt]; int m=(l+r)>>1,temp=0; if(R<=m) return query(L,R,lson); else if(L>m) return query(L,R,rson); else { temp+=query(L,R,lson); temp+=query(L,R,rson); return temp; }}void pushup(int rt) //向上更新,每次插入的时候向上更新,注意是覆盖{ sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void update(int target,int l,int r,int rt){ if(l==r) { sum[rt]++; return ; } int m=(l+r)>>1; if(target<=m) update(target,lson); else update(target,rson); pushup(rt); return ;}int main(){ int n,temp; while(scanf("%d",&n)!=EOF) { int sum=0; build(0,n-1,1); //注意区间是0-(n-1) for(int i=1;i<=n;i++) { scanf("%d",&save[i]); sum+=query(save[i],n-1,0,n-1,1); update(save[i],0,n-1,1); } int ans=sum; for(int i=1;i<n;i++) { sum+=n-2*save[i]-1; ans=min(sum,ans); } printf("%d\n",ans); } return 0;}
- hdu 1394 Minimum Inversion Number(线段树 单点更新)
- hdu 1394 Minimum Inversion Number(线段树单点更新)
- hdu 1394 Minimum Inversion Number(线段树-单点更新)
- HDU 1394 Minimum Inversion Number [线段树->单点更新]【数据结构】
- hdu 1754 Minimum Inversion Number 线段树 单点更新
- HDU 1394 Minimum Inversion Number(单点更新)
- ZOJ 1484 HDU 1394 Minimum Inversion Number / 线段树单点更新
- HDU 1394 Minimum Inversion Number(线段树:单点更新,区间求和)
- hdu 1394 Minimum Inversion Number(线段树之 单点更新求逆序数)
- HDU 1394 Minimum Inversion Number (线段树 单点更新 求逆序数)
- HDU - 1394 - Minimum Inversion Number (线段树 - 单点更新,区间求和)
- HDU 1394 Minimum Inversion Number(线段树:单点更新,求逆序数)
- HDU 1394 Minimum Inversion Number(线段树:单点更新,区间求和)
- HDU 1394 Minimum Inversion Number 线段树 单点更新 求逆序数
- HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
- hdu 1394 Minimum Inversion Number 线段树 点更新
- HDU1394 Minimum Inversion Number [暴力] [线段树-单点更新]
- Minimum Inversion Number----HDU_1394----线段树之单点更新
- int string CStirng的相互装换
- 使用C++实现简单的正则表达式
- C++及Windows异常处理(try,catch; __try,__finally; __try, __except)
- 完整的游戏数据包下载安装教程
- sizeof strlen length 之区别
- hdu 1394 Minimum Inversion Number(线段树 单点更新)
- SCI与SPI区别
- 第一节:准备工作
- 【联大CSDN第一期】IT职业发展规划
- Jquery学习集锦
- 七 Strings类(一)
- 【联大CSDN第三期预告】玩转苹果系统及ios开发入门
- .Net常用事务(了解一下)
- 七 Strings类(二)