hdu-5592 ZYB's Premutation(线段树)

来源:互联网 发布:金域名人国际酒店ktv 编辑:程序博客网 时间:2024/06/05 11:52

ZYB's Premutation

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 977    Accepted Submission(s): 496


Problem Description
ZYB has a premutation P,but he only remeber the reverse log of each prefix of the premutation,now he ask you to
restore the premutation.

Pair (i,j)(i<j) is considered as a reverse log if Ai>Aj is matched.
 

Input
In the first line there is the number of testcases T.

For each teatcase:

In the first line there is one number N.

In the next line there are N numbers Ai,describe the number of the reverse logs of each prefix,

The input is correct.

1T5,1N50000
 

Output
For each testcase,print the ans.
 

Sample Input
130 1 2
 

Sample Output
3 1 2
 

Source
BestCoder Round #65

 

题意:给出一个序列P位置i的逆序前缀,要求还原这个序列,定义i<j且Ai>Aj时Ai为Aj的逆序
题解:先把逆序前缀分解成位置i的逆序,只要用a[i]-a[i-1]即可.然后反向遍历,对于位置i,逆序为a[i],那么设在位置i+1~n中,比i大的数出现了x个,
那么位置i的数的大小就是n-a[i]-x

/*题意:给出一个序列P位置i的逆序前缀,要求还原这个序列,定义i<j且Ai>Aj时Ai为Aj的逆序题解:先把逆序前缀分解成位置i的逆序,只要用a[i]-a[i-1]即可.然后反向遍历,对于位置i,逆序为a[i],那么设在位置i+1~n中,比i大的数出现了x个,那么位置i的数的大小就是n-a[i]-x,过程用线段树维护一下就可以了
*/#include<cstdio>#include<algorithm>#include<string.h>#include<stdlib.h>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int maxn = 5e4 + 5;int sum[maxn<<2],a[maxn],ans[maxn];void PushUP(int rt){    sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(int l,int r,int rt){    if(l==r) {sum[rt]=1;return;}    int m=(l+r)>>1;    build(lson);    build(rson);    PushUP(rt);}int query(int x,int l,int r,int rt){    if(l==r) {sum[rt]=0;return l;}    int m=(l+r)>>1;    int ret=0;    if(sum[rt<<1|1]<=x) ret=query(x-sum[rt<<1|1],lson);    else ret=query(x,rson);    PushUP(rt);    return ret;}int main(){    int T,n;    //freopen("in.txt","r",stdin);    scanf("%d",&T);    while(T--){        scanf("%d",&n);        for(int i=1;i<=n;i++) scanf("%d",&a[i]);        build(1,n,1);        for(int i=n;i>0;i--) {            a[i]-=a[i-1];      //得到位置i的逆序数            int x=query(a[i],1,n,1);            ans[i]=x;        }        for(int i=1;i<=n;i++) printf("%d%c",ans[i],i==n?'\n':' ');    }    return 0;}


1 0
原创粉丝点击