• BestCoder Round #65 HDOJ5592 ZYB's Premutation(树状数组+二分)


    ZYB's Premutation

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


    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
    1 3 0 1 2
     

    Sample Output
    3 1 2
     



    题目链接:点击打开链接

    能够想到a[i] - a[i - 1]为i前比a[i]大的数的个数, 从后向前遍历, 通过二分与树状数组确定i应当填入的位置.

    AC代码:

    #include "iostream"
    #include "cstdio"
    #include "cstring"
    #include "algorithm"
    #include "queue"
    #include "stack"
    #include "cmath"
    #include "utility"
    #include "map"
    #include "set"
    #include "vector"
    #include "list"
    #include "string"
    using namespace std;
    typedef long long ll;
    const int MOD = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    const int MAXN = 5e4 + 5;
    int n, a[MAXN], c[MAXN], ans[MAXN];
    int lowbit(int x)
    {
    	return x & (-x);
    }
    void update(int x, int y)
    {
    	while(x <= n) {
    		c[x] += y;
    		x += lowbit(x);
    	}
    }
    int get_sum(int x)
    {
    	int sum = 0;
    	while(x > 0) {
    		sum += c[x];
    		x -= lowbit(x);
    	}
    	return sum;
    }
    int binary_search(int x)
    {
    	int l = 1, r = n, m;
    	while(l <= r) {
    		m = (l + r) >> 1;
    		if(get_sum(m) >= x) r = m - 1;
    		else l = m + 1;
    	}
    	return l;
    }
    int main(int argc, char const *argv[])
    {
    	int t;
    	scanf("%d", &t);
    	while(t--) {
    		memset(c, 0, sizeof(c));
    		memset(ans, 0, sizeof(ans));
    		scanf("%d", &n);
    		for(int i = 1; i <= n; ++i)
    			scanf("%d", &a[i]);
    		for(int i = n; i >= 1; --i)
    			a[i] -= a[i - 1];
    		for(int i = 1; i <= n; ++i)
    			update(i, 1);
    		for(int i = n; i >= 1; --i) {
    			int pos = i - a[i] - 1;
    			ans[i] = binary_search(pos + 1);
    			update(ans[i], -1);
    		}
    		for(int i = 1; i < n; ++i)
    			printf("%d ", ans[i]);
    		printf("%d
    ", ans[n]);
    	}
    	return 0;
    }


  • 相关阅读:
    Android虚拟、实体键盘不能同时使用?
    libwebsockets 运行问题
    Qt TabWidget QTabBar 宽高设置
    I.MX6 recovery mode hacking
    libwebsockets libwebsockets-webserver.c hacking
    MySQL(六)常用语法和数据类型
    MySQL(五)汇总和分组数据
    MySQL(四)字段及常用函数
    MySQL(三)用正则表达式搜索
    MySQL(二)数据的检索和过滤
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/6961671.html
Copyright © 2020-2023  润新知