hdu1394 线段树 / 树状数组
来源:互联网 发布:js获取指定日期前一天 编辑:程序博客网 时间:2024/06/08 13:34
题目:就是求一个数组的逆序数,然后依次将数组的第一个数调到最后,最后求出最小的逆序数
做了两种,线段树和树状数组
//利用线段树求逆序数 // 每次将数字x插到线段树的 x 位置,然后球一下,该线段树右边的和,即为逆序数的个数 //第一次用线段树,做这个。。 #include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;#define maxn 5555int sum[maxn<<2];int x[maxn];/*void build(int l,int r,int rt)//其实build 可以省略 { sum[rt]=0; if(l==r)return ; int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); }*/void build(int l,int r,int rt){memset(sum,0,sizeof(sum));} void push_up(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void update(int p,int l,int r,int rt){if(l==r){sum[rt]++; //而不是直接赋值为1,因为还可能有重复的值插入return ; }int mid=(l+r)>>1;if(p<=mid)update(p,l,mid,rt<<1);else update(p,mid+1,r,rt<<1|1);push_up(rt);}int query(int L,int R,int l,int r,int rt){if(L<=l && R>=r)return sum[rt];int mid=(l+r)>>1;int res=0;if(L<=mid)res+=query(L,R,l,mid,rt<<1);if(R>mid)res+=query(L,R,mid+1,r,rt<<1|1);return res;}int main(){//freopen("q.in","r",stdin);int n;int i,j; while(~scanf("%d",&n)) { int ret=0; memset(x,0,sizeof(x));build(0,n-1,1);for(i=0;i<n;i++){scanf("%d",&x[i]);ret+=query(x[i],n-1,0,n-1,1); update(x[i],0,n-1,1);}int ans=ret;for(i=0;i<n;i++){ret+=n-x[i]-x[i]-1;ans=min(ret,ans);//最后找出所有序列中的最小逆序数 }cout<<ans<<endl; }}
#include <cstdio>#include<cmath>#include<cstring>#include<iostream>using namespace std;int n;int c[5005*4];int a[5005];inline int lowbit(int x){ return (x&-x);}void add(int x,int value){ for(int i=x;i<=n;i+=lowbit(i)) c[i]+=value;}int sum(int x) //找出x前面比x小的数的个数{ int sum=0; for(int i=x;i;i-=lowbit(i)) sum+=c[i]; return sum;}int main(){ // freopen("q.txt","r",stdin); while(scanf("%d",&n)==1) { int res=0; memset(c,0,sizeof(c)); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); a[i]++; // cout<<lowbit(a[i])<<"& "; add(a[i],1); res+=(i-sum(a[i])); } int mmin=5000000; for(int i=1;i<=n;i++) { res=res-(a[i]-1)+(n-a[i]); mmin=min(mmin,res); } cout<<mmin<<endl; }}
其实。。。以前用过线段树,但总觉得自己没有领悟到本质。。~~~~(>_<)~~~~ 还需要再认真思考啊,总是参照别人对的代码,当然很容易作对啊
0 0
- hdu1394 线段树 / 树状数组
- (hdu1394)Minimum Inversion Number (树状数组/线段树/归并排序)
- hdu1394 Inversion后的最小逆序数 线段树 树状数组
- hdu1394树状数组
- hdu1394 树状数组 解法
- hdu1394~线段树求和
- 线段树,树状数组
- 线段树,树状数组
- 线段树,树状数组
- 线段树,树状数组
- 树状数组-线段树
- 线段树 && 树状数组
- 线段树,树状数组
- 线段树&&树状数组
- 线段树+树状数组
- HDU1394用树状数组求逆序数
- hdu1394求最小逆序----树状数组解决
- hdu1394 Minimum Inversion Number 树状数组
- acm_icpc网络赛第五站:北京赛区
- VMware Ubuntu samba配置和自动启动root账户的设置和其他配置
- 37 最长字符串链接
- 如何用C实现一个类以及些许设计模式
- 编程珠玑(一)
- hdu1394 线段树 / 树状数组
- akoj-1204-支配值数目
- 增加一个 AVFormat 格式:PES
- 膨胀,腐蚀,开运算和闭运算
- 链表、头指针、头结点
- 38 百度面试 天平,url等
- 抓包,第三方数据提取和使用
- 树的高度
- 共用体