hdu5592

来源:互联网 发布:电子政务系统源码 编辑:程序博客网 时间:2024/06/05 21:08

链接:点击打开链接

题意:给出A[1]到A[n],A[i]的意义为1~i位每一位逆序数的和,输出这个数列

代码:

#include <stack>#include <cstdio>#include <cstring>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;int n,bit[50005];int sum(int i){    int s=0;    while(i>0){        s+=bit[i];        i-=i&-i;    }    return s;}void add(int i,int x){    while(i<=n){        bit[i]+=x;        i+=i&-i;    }}int main(){    int t,i,j,l,r,mid,ans;    int A[50005],a[50005];    scanf("%d",&t);    while(t--){                             //数列的每一位就是没有用过的数中第A[i]-A[i-1]+1大的数//        stack<int> s;        memset(bit,0,sizeof(bit));        scanf("%d",&n);        A[0]=0;        for(i=1;i<=n;i++){        scanf("%d",&A[i]);        add(i,1);        }        for(i=n;i>=1;i--)        A[i]=i-(A[i]-A[i-1]);               //将A[i]转换为i之前有多少个数比i小        for(i=n;i>=1;i--){            l=1,r=ans=n;            while(l<=r){                mid=(l+r)/2;//                cout<<l<<" "<<r<<" "<<mid<<" "<<sum(mid)<<endl;                if(sum(mid)>=A[i]){         //二分这个数是多少                r=mid-1;                ans=mid;                }                else                l=mid+1;            }//            cout<<"l=="<<ans<<endl;            a[i]=ans;            add(ans,-1);        }        for(i=1;i<=n;i++)        printf("%d%c",a[i],i==n?'\n':' ');    }    return 0;}

0 0
原创粉丝点击