zoukankan      html  css  js  c++  java
  • hdu 5592 ZYB's Game 树状数组

    ZYB's Game

    Time Limit: 20 Sec

    Memory Limit: 256 MB

    题目连接

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

    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:

    the first line there is one number N.

    1T100000,1N10000000

    Output

    For each testcase,print the ans.

    Sample Input

    1
    3
    0 1 2

    Sample Output

    3 1 2

    HINT

    题意

     

    题解:

    很显然可以发现,a[i]-a[i-1],就表示在[1,i]中比i大的数有多少个

    那么我们倒着做就好了,拿一个树状数组来维护就行了~

    代码:

    #include<iostream>
    #include<stdio.h>
    #include<cstring>
    using namespace std;
    #define maxn 50005
    long long a[maxn];
    int ans[maxn];
    #define lowbit(x) ((x)&(-x))
    
    struct BinaryIndexTree
    {
        int val[maxn],sz;
    
        void init(int sz){
            this->sz=sz;
            memset(val , 0 , sizeof(int)*(sz+5));
        }
    
        void updata(int pos ,int key){
            while(pos<=sz){
                val[pos]+=key;
                pos+=lowbit(pos);
            }
        }
    
        long long prefixsum(int pos){
            long long res=0;
            while(pos>0){
                res+=val[pos];
                pos-=lowbit(pos);
            }
            return res;
        }
    
        int query(int l,int r){
            return prefixsum(r)-prefixsum(l-1);
        }
    
        //到第一个大于等于k的位置返回
        //若不存在,返回-1
        int lower_bound(long long k){
            if(prefixsum(sz)<k) return -1;
            int l = 1 , r = sz;
            while(l <= r){
                int mid = l + ((r-l)>>1);
                if(prefixsum(mid) < k) l = mid + 1;
                else r = mid - 1;
            }
            return l;
           }
    
    }solver;
    
    long long c[maxn];
    int main()
    {
        int t;scanf("%d",&t);
        for(int cas=1;cas<=t;cas++)
        {
            memset(a,0,sizeof(a));
            memset(c,0,sizeof(c));
            int n;scanf("%d",&n);
            for(int i=1;i<=n;i++)
                scanf("%I64d",&a[i]);
            for(int i=1;i<=n;i++)
                c[i]=a[i]-a[i-1];
            solver.init(n);
            for(int i=1;i<=n;i++)
                solver.updata(i,1);
            int tmp = 0;
            for(int i=n;i>=1;i--)
            {
                ans[i]=solver.lower_bound(n-tmp-c[i]);
                solver.updata(ans[i],-1);
                tmp++;
            }
            for(int i=1;i<=n;i++)
            {
                if(i!=n)
                    printf("%d ",ans[i]);
                else printf("%d
    ",ans[i]);
            }
        }
    }
  • 相关阅读:
    C# 并行线程调用
    Oracle定时备份
    读取Excel里面的内容转为DataTable
    c# 将json数据转为键值对
    Py基础+中级
    深入理解DIP、IoC、DI以及IoC容器(转载)
    错误页面的配置
    JavaScript重载
    关于为空必填js判断
    MyEclipse CI 2018.8.0正式发布(附下载)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5023329.html
Copyright © 2011-2022 走看看