首页 > 代码库 > HDU_1394_线段数
HDU_1394_线段数
http://acm.hdu.edu.cn/showproblem.php?pid=1394
线段数入门题,每次读入一个数,就寻找在树中比它大的值的个数,然后跟新数,把个数相加就是逆序数,每移动一个数,相当于当前逆序数加上比首元素大的数的数量,减去比首元素小的数的数量。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct segtree{ int left,right,sum;}tree[10050];int n,a[5050];void build(int pos,int l,int r){ tree[pos].left = l; tree[pos].right = r; tree[pos].sum = 0; if(l < r) { int mid = (l+r)/2; build(pos*2,l,mid); build(pos*2+1,mid+1,r); }}int getsum(int pos,int l,int r){ if(tree[pos].left == l && tree[pos].right == r) return tree[pos].sum; int mid = (tree[pos].left+tree[pos].right)/2; if(r <= mid) return getsum(pos*2,l,r); if(l > mid) return getsum(pos*2+1,l,r); return getsum(pos*2,l,mid)+getsum(pos*2+1,mid+1,r);}void update(int pos,int num){ tree[pos].sum++; if(tree[pos].left == tree[pos].right) return; int mid = (tree[pos].left+tree[pos].right)/2; if(num <= mid) update(pos*2,num); else update(pos*2+1,num);}int main(){ while(~scanf("%d",&n)) { int ans = 0; build(1,0,n-1); for(int i = 0;i < n;i++) { scanf("%d",&a[i]); ans += getsum(1,a[i],n-1); update(1,a[i]); } int temp = ans; for(int i = 0;i < n-1;i++) { temp += n-1-a[i]-a[i]; ans = min(temp,ans); } printf("%d\n",ans); } return 0;}
HDU_1394_线段数
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。