hdu5122 K.Bro Sorting

来源:互联网 发布:远景论坛 知乎 编辑:程序博客网 时间:2024/05/22 01:42

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5122

思路:

可以用线段树,树状数组,模拟都可。

线段树和树状数组都可以利用逆序数来看。

线段树可以按照顺序插入这些数,然后可以查询在这个数后面的是否有比他小的数,一旦有就ans++。

树状数组可以从后往前插入,每次插入查询是否已经有比他小的插在他后面了,如果有就ans++。

直接模拟的话,就是从后往前看,如果当前的值大于最小值就ans++,并且记录过程中的最小值。

其实就是看一个数后面有没有比他小的数,然后做一下统计。


代码:

树状数组:

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct node { int a,num;}p[1000005];int n,d[1000005];bool cmp(node x,node y){    return x.a>y.a;}int lowbit(int x){    return x&(-x);}void update(int x){    while(x<=n)    {        d[x]++;        x+=lowbit(x);    }}int query(int x){    int ans=0;    while(x>0)    {        ans+=d[x];        x-=lowbit(x);    }    return ans;}int main(){    int T,i,j,k,icase=0;    scanf("%d",&T);    while(T--)    {        icase++;        scanf("%d",&n);        for(i=1;i<=n;i++)            {                scanf("%d",&p[i].a);              p[i].num=i;    }    memset(d,0,sizeof(d));   // sort(p+1,p+1+n,cmp);    int sum=0;    for(i=n;i>=1;i--)    {        if(query(p[i].a))sum++;         update(p[i].a);    }    printf("Case #%d: ",icase);    printf("%d\n",sum);    }}


模拟:

#include<stdio.h>#include<string.h>int min(int a,int b){    if(a<b)return a;    else return b;}int a[1000005];int main(){    int T,i,j,k,n,icase=0;    scanf("%d",&T);    while(T--)    {        icase++;        scanf("%d",&n);        for(i=1;i<=n;i++)            scanf("%d",&a[i]);        int ans=0,mini;        mini=a[n];        for(i=n-1;i>=1;i--)        {            if(a[i]>mini)ans++;            mini=min(mini,a[i]);        }        printf("Case #%d: ",icase);        printf("%d\n",ans);    }}




0 0
原创粉丝点击